【问题标题】:Big collections in DDD using Entity Framework使用实体框架的 DDD 中的大集合
【发布时间】:2015-08-19 04:54:08
【问题描述】:

我尝试使用 DDD 来描述域模型和代码优先方法,以使用实体框架(使用 fluent api)映射到数据库表。 例如,我有 2 个实体:俱乐部和用户。俱乐部有很多用户。我需要将新用户添加到俱乐部。

class User 
{
    public string Name { get; set; }
    public Club Club { get; set; }
}

class Club
{
    public string ClubName { get; set; }
    public ICollection<User> Members { get; set; }

    public void AddNewMember(User user)
    {
        //..some logic and checks
        Members.Add(user);
    }
}
  1. 那么,我应该加载 Club 中的所有用户收藏以添加新的并保存吗?还是过分了?
  2. 为具有大集合的实体建模的最佳方法是什么?我应该总是加载它们吗?或者移动到另一个单独的对象?

【问题讨论】:

  • 一个用户只能属于一个俱乐部吗?你还需要强制执行哪些不变量?
  • @Marco,是的,用户只属于一个俱乐部。我需要检查一些规则——在我的例子中很简单,但我对使用相关实体的集合有疑问。

标签: c# entity-framework domain-driven-design


【解决方案1】:

如何引入一个新的域概念“会员”。成员可以是一个聚合体并拥有自己的专用回​​购。或者您只需关闭原始设计的延迟加载并将其添加到其集合中。这一切都取决于您的业务规则。

public class User
{
    public Guid UserId { get; set; }
}

public class Member
{
    public Guid ClubId { get; set; }

    public Guid UserId { get; set; }
}

public class Club
{
    public Guid ClubId { get; set; }

    public Member RegisterMember(User user)
    {
        // Check business rules..

        return new Member { UserId = user.Id, ClubId = this.ClubId };
    }
}

【讨论】:

  • 这很有趣。我会思考如何以最合适的方式实施这种方法。谢谢你的想法
  • 但这是一个多对多关联,而 OP 声明它是 1-many。
  • OP 在问题标题中提到了 DDD,所以我们真的需要弄清楚他是否真的在尝试使用纯域模型或数据模型。您可以使用 fluent api 将其配置为一对多。用户很可能包含用户名和密码/安全内容。而 member 更多的是一个域概念。它也可以建模为 VO,但我们需要更多上下文来确定所有这些
【解决方案2】:

我应该在 Club 中加载所有用户收藏以添加新的并保存吗?

不,您可以将新的User 添加到Club.Members,EF 将保存新用户。不必先加载用户。

用大集合建模实体的最佳方法是什么

这并不取决于集合的潜在大小,而是取决于您计划如何访问它们。如果有Clubs 和数千个Users,那么如果您想通过这样的查询来查询一小部分用户,那么没有任何异议:

from c in Clubs
from u in c.Users
where c.Type = "Golf" && u.Membership = "Gold"
select u

我总是鼓励使用导航属性。 EF 实体模型首先用于访问数据库。 DDD 问题是次要的。

当然,除非您确实需要,否则您可能应该始终阻止加载俱乐部的所有用户的查询。

【讨论】:

  • 我完全同意这一点
  • "不,您可以向 Club.Members 添加新用户,EF 将保存新用户。无需先加载用户。" - 如果你想检查不添加用户两次怎么办?
  • @dariol 那是另一回事。那将需要“upsert”逻辑。但问题是“添加新并保存”。
【解决方案3】:

好吧,根据我从您的场景中可以看出,为您的集合使用 virtual 关键字并让 Entity Framework 延迟加载您的集合可能是有意义的

https://msdn.microsoft.com/en-gb/data/jj574232

基本上让 Entity Framework 为你完成工作

【讨论】:

  • 这将是一种浪费,除非他有与其他成员交叉的逻辑,我怀疑是这种情况。
  • 嗯,它直接回答了问题 1 和 2。我不明白它是如何浪费的?他的问题并不是我阅读它的方式,而是关于如何使用 EF 加载相关对象,最常见的方法是使用延迟加载,除非有特定原因“关闭它”正如链接文章所说的那样
  • 我可以想象一个拥有数千名会员的俱乐部。你真的想加载整个集合只是为了添加一个新用户吗?我希望不会。老实说,我们没有足够的背景来给他一个纯粹的答案
  • 数千并没有那么高。但我认为延迟加载无论如何都解决了这个问题,linq 查询将决定加载什么以及检索和保存在内存中的数量。不会加载整个集合以添加新用户。这几乎是重点
  • 有时 thouthands 并不多。也许我不需要俱乐部实体中的用户集合,而只需使用直接保存到数据库上下文。但这不是 DDD 方式,我需要将逻辑从 Club 对象转移到一些“服务”...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 2018-12-06
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多