我正在努力研究聚合和聚合根.我有一个自然聚合根,适用于大约60%的用户请求.即这些请求自然适用于聚合根.
在我的聚合中,我有另一个实体,它只能作为聚合根的成员存在.但是,用户将被告知这个其他实体对象.从概念上讲,用户有时可以直接对此非聚合根对象进行操作.
所以,我想我有几个选择:
请注意,顶级聚合根将包含此其他实体的集合.
例:
主要集合根:汽车
第二个实体:座位(根据类型,汽车有2个或4个座位).在我的域名中,座位只能作为汽车的一部分存在.
域中的大多数操作都在Car级别.所以这将是聚合根的一个很好的候选者.然而,(我在这里努力争取示例),一些操作将在座位级别,例如SpillCoffee,ChangeFabric,Clean ....
座椅和汽车都可以是聚合根?或者我应该始终从汽车开始?
谢谢
鉴于数据库中的以下事实:
foo(a, 3).
foo(b, 2).
foo(c, 4).
foo(d, 3).
foo(e, 2).
foo(f, 6).
foo(g, 3).
foo(h, 2).
Run Code Online (Sandbox Code Playgroud)
我想收集所有具有最小第二个参数的第一个参数,加上第二个参数的值.第一次尝试:
find_min_1(Min, As) :-
setof(B-A, foo(A, B), [Min-_|_]),
findall(A, foo(A, Min), As).
?- find_min_1(Min, As).
Min = 2,
As = [b, e, h].
Run Code Online (Sandbox Code Playgroud)
而不是setof/3,我可以使用aggregate/3:
find_min_2(Min, As) :-
aggregate(min(B), A^foo(A, B), Min),
findall(A, foo(A, Min), As).
?- find_min_2(Min, As).
Min = 2,
As = [b, e, h].
Run Code Online (Sandbox Code Playgroud)
NB
如果我正在寻找最小数字,这只会给出相同的结果.如果涉及算术表达式,结果可能会有所不同.如果涉及非数字,aggregate(min(...), ...)将抛出错误!
或者,我可以使用完整的键排序列表:
find_min_3(Min, As) :-
setof(B-A, foo(A, …Run Code Online (Sandbox Code Playgroud) 我需要帮助找到我的聚合根和边界.
我有3个实体:Plan,PlannedRole和PlannedTraining.每个计划都可以包含许多PlannedRoles和PlannedTraining.
解决方案1:起初我认为Plan是聚合根,因为PlannedRole和PlannedTraining在计划的上下文中没有意义.他们总是在计划之内.此外,我们有一个业务规则,即每个计划最多可以有3个PlannedRoles和5个PlannedTraining.所以我认为通过提名计划作为聚合根,我可以强制执行这个不变量.
但是,我们有一个搜索页面,用户可在其中搜索计划.结果显示了计划本身的一些属性(而不是PlannedRoles或PlannedTrainings).我想如果我必须加载整个聚合,它会有很多开销.有近3000个计划,每个计划可能有几个孩子.将所有这些对象加载到一起然后忽略搜索页面中的PlannedRoles和PlannedTraining对我来说没有意义.
解决方案2:我刚刚意识到用户还需要2个搜索页面,他们可以搜索计划角色或计划培训.这让我意识到他们正试图独立地访问这些对象并"脱离"Plan的背景.所以我认为我的初始设计错了,这就是我想出这个解决方案的方法.所以,我认为这里有3个聚合,每个实体有1个聚合.
这种方法使我能够独立搜索每个实体,并解决了解决方案1中的性能问题.但是,使用这种方法我不能强制执行前面提到的不变量.
还有另一个不变量,即只有在具有特定状态时才能更改计划.因此,我不能将任何PlannedRoles或PlannedTrainings添加到不处于该状态的计划中.同样,我不能用第二种方法强制执行这种不变量.
任何建议将不胜感激.
干杯,莫什
我一直试图在PostgreSQL(8.4或9.1)中创建接受一个或多个选项参数的聚合.
一个例子是创建一个PL/R扩展来计算第p个分位数0 <= p <= 1.这看起来像quantile(x,p),并作为查询的一部分:
select category,quantile(x,0.25)
from TABLE
group by category
order by category;
Run Code Online (Sandbox Code Playgroud)
哪里TABLE (category:text, x:float).
建议?
我有一个我想要计算聚合的产品目录.这对于顶级属性(如品牌名称,制造商等)来说非常简单.尝试计算价格的范围计数时会出现问题,因为我们以多种货币进行销售,而在确定这些计数时,我只想查询一种货币.时间.以下是我的产品对象映射示例:
public class Product
{
public int ID { get; set;}
public string Name { get; set; }
public IList<Price> Prices { get; set; }
}
public class Price
{
public int CurrencyID { get; set; }
public decimal Cost { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以下是价格低于100的所有产品的查询示例:
var cheapProducts = client.Search<Product>(s => s
.From(0)
.Size(1000)
.Query(q => q
.Range(r => r
.LowerOrEquals(100)
.OnField(f => f.Prices.FirstOrDefault().Cost))));
Run Code Online (Sandbox Code Playgroud)
这会生成的ElasticSearch请求是:
{
"from": 0,
"size": 1000,
"query": {
"range" : {
"prices.cost": {
"lte": "100"
} …Run Code Online (Sandbox Code Playgroud) 在DDD中,存储库用于执行聚合的序列化和反序列化,例如通过读取和写入数据库.这样,聚合可以包含更纯粹的业务逻辑,并且不会与非特定于域的持久性策略相关联.
但是,我想知道为什么存储库总是被描述为专门用于聚合.是否同样有动力将它用于所有实体?
(如果这只是一个事实,即所有普通实体都可以看作是零孩子的集合根,请告知我这个问题,这个问题可以埋没.)
oop domain-driven-design repository aggregateroot aggregates
我正在尝试将一些SQL查询转换为Linq,以避免多次访问数据库.
我正在尝试转换的旧SQL:
SELECT
AVG(CAST(DATEDIFF(ms, A.CreatedDate, B.CompletedDate) AS decimal(15,4))),
AVG(CAST(DATEDIFF(ms, B.CreatedDate, B.CompletedDate) AS decimal(15,4)))
FROM
dbo.A
INNER JOIN
dbo.B ON B.ParentId = A.Id
Run Code Online (Sandbox Code Playgroud)
所以我创建了两个C#类:
class B
{
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime CompletedDate { get; set; }
}
class A
{
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public List<B> BList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个List<A>我想查询的对象.它是从数据库填充的,因此列表中的每个A都有一个负载为Bs的子列表.我想使用Linq-to-objects来查询此列表.
所以我需要使用Linq来获得A开始和孩子Bs完成之间的平均时间,以及每个B开始和完成之间的平均时间.我没有写原始的SQL所以我不完全确定它做了它应该做的!
我有几个这些平均值要计算,所以我想在一个神奇的Linq查询中完成它们.这可能吗?
我有一个优惠券模型,它有一些字段来定义它是否处于活动状态,以及一个只返回实时优惠券的自定义管理器.优惠券有一个FK到项目.
在对项目的查询中,我试图注释可用的有效优惠券的数量.但是,Count聚合似乎在计算所有优惠券,而不仅仅是活跃优惠券.
# models.py
class LiveCouponManager(models.Manager):
"""
Returns only coupons which are active, and the current
date is after the active_date (if specified) but before the valid_until
date (if specified).
"""
def get_query_set(self):
today = datetime.date.today()
passed_active_date = models.Q(active_date__lte=today) | models.Q(active_date=None)
not_expired = models.Q(valid_until__gte=today) | models.Q(valid_until=None)
return super(LiveCouponManager,self).get_query_set().filter(is_active=True).filter(passed_active_date, not_expired)
class Item(models.Model):
# irrelevant fields
class Coupon(models.Model):
item = models.ForeignKey(Item)
is_active = models.BooleanField(default=True)
active_date = models.DateField(blank=True, null=True)
valid_until = models.DateField(blank=True, null=True)
# more fields
live = LiveCouponManager() # defined first, should …Run Code Online (Sandbox Code Playgroud) 我有一个关于使用我的数据模型实现存储库模式的问题.我在网上搜索并查看了很多帖子,但我找不到任何能够解决我怀疑的答案.基本上我们的域模型如下所示,我们有一个客户端对象,它有很多子对象,而一些子对象又有一个子对象,在任何时候这些子对象都不需要父对象,也不需要应用程序中的任何意义.
client
--> client zip codes
--> client phone history
--> client medical history
--> client direct services
--> client direct service assessments
--> client direct service risk reductions
--> client housing
--> client housing landlord
Run Code Online (Sandbox Code Playgroud)
它就是这样的.所以从上面的表示我有一些聚合,根是客户端对象,所以我想在聚合根级别创建一个存储库,这是客户端.我的问题是如何处理其他聚合.谁能请我就此提出一些想法.
谢谢,Ajay.
aggregateroot repository-pattern aggregates entity-framework-4
我的团队需要找到以下问题的解决方案:
我们的应用程序允许用户查看企业的总销售额,按产品划分的总计,按地区划分的总数,按地区x产品划分的总数,按地区划分的总数等.您可以了解相关信息.有许多值需要聚合以获得许多无法动态计算的总数 - 我们必须预先聚合它们以提供合适的响应时间,这个过程大约需要5分钟.
问题,我们认为是一个常见的问题,但没有参考,是如何在不关闭用户的情况下允许更新各种销售.此外,用户无法接受最终的一致性 - 如果他们总共向下钻取12个,他们最好看到总数为12的数字.因此,我们需要一致性+可用性.
到目前为止,我们提出的最佳解决方案是将所有查询定向到冗余数据库,"B"(针对查询进行了优化),同时将更新定向到主数据库"A".当我们决定花5分钟更新所有聚合时,我们更新数据库"C",这是另一个冗余数据库,就像"B"一样.然后,新用户会话被定向到"C",而现有用户会话继续使用"B".最后,警告任何人使用"B",我们杀死"B"上的会话并在那里重新聚合,交换"B"和"C"的角色.典型的排水停止方案.
我们感到惊讶的是,我们无法找到任何关于此的讨论,并担心我们过度设计这个问题,或者可能不是我们认为的问题.任何建议都非常感谢.
aggregates ×10
c# ×2
sql ×2
.net ×1
aggregate ×1
average ×1
backtracking ×1
caching ×1
consistency ×1
count ×1
django ×1
linq ×1
nest ×1
oop ×1
orm ×1
postgresql ×1
prolog ×1
prolog-setof ×1
repository ×1