简体   繁体   English

如何在使用带有DDD方法的EF Code First时正确定义DbContext派生类?

[英]How to properly define DbContext derived class when using EF Code First with DDD methodology?

I am new to EF, Code First and DDD and still in the learning process, so let's say I have simple domain like this 我是EF,Code First和DDD的新手,仍处于学习过程中,所以我想说我有这样简单的域名

public class Customer
{
    public string Name { get; set; }
    public string Address { get; set; }

    public List<Order> Orders { get; set; }
}

public class Order
{
    public DateTime OrderDate { get; set; }
    public List<LineItem> LineItems { get; set; }
}

public class LineItem
{
    public Product Product { get; set; }
    public int Quantity { get; set; }
}

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

After domain is defined the next step is to create DbContext derived class and my question is how should it look like? 在定义域之后,下一步是创建DbContext派生类,我的问题是它应该是什么样子? What is a context class definition driven by? 什么是上下文类定义? Is it by the use cases of the final application? 是最终申请的用例吗?

For example, looking at the domain above we can see that given the Customer instance we can access any child object. 例如,查看上面的域,我们可以看到,给定Customer实例,我们可以访问任何子对象。 So is it then enough to make the context class contains only Customers property look like this: 那么就足以使上下文类只包含Customers属性如下所示:

class MyContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}

With this I can browse customers from my app and then select one to see details and orders history etc... Looks good for now. 有了这个,我可以从我的应用程序浏览客户,然后选择一个查看详细信息和订单历史记录等...现在看起来不错。

Now let's say I want following feature in my application: - list last 10 orders in store (no matter who was the customer) - list all orders with specific product in it 现在让我说我想在我的应用程序中使用以下功能: - 列出商店中的最后10个订单(无论是谁是客户) - 列出包含特定产品的所有订单

I guess that this data can be pulled from the current context right? 我想这个数据可以从当前的上下文中拉出来吗? Eg. 例如。 last 10 orders: 最后10个订单:

        using (var context = new MyContext())
        {
            var lastTenOrders = context.Customers.Include("Orders")
                                             .Select(customer => customer.Orders)
                                             .SelectMany(orderList => orderList)
                                             .OrderByDescending(order => order.OrderDate)
                                             .Take(10)
                                             .ToList();
        }

And getting all orders that contain product with Id = 5: 并获取包含Id = 5的产品的所有订单:

        using (var context = new MyContext())
        {
            int productId = 5;

            var lastTenOrders = context.Customers.Include("Orders")
                                             .Select(customer => customer.Orders)
                                             .SelectMany(orderList => orderList)
                                             .Where(order => order.LineItems.Where(i => i.Product.Id == productId).Any())
                                             .ToList();

        }

(note I didn't test these queries so not sure if they work but they describe my general idea) (注意我没有测试这些查询,因此不确定它们是否有效但是它们描述了我的总体想法)

So I guess this would work but I am wondering is this the right path. 所以我想这会奏效,但我想知道这是正确的道路。 Queries can get pretty complex here and it would probably be easier if I add say Orders and Products to the DbContext: public class MyContext : DbContext { public DbSet Customers { get; 查询在这里会变得非常复杂,如果我向DbContext添加说明订单和产品可能会更容易:公共类MyContext:DbContext {public DbSet Customers {get; set; 组; } public DbSet Orders { get; 公共DbSet订单{get; set; 组; } public DbSet Products { get; } public DbSet Products {get; set; 组; } } }}

On the other hand I am not sure if I should add orders since they can already be retrieved from the Customer etc... 另一方面,我不确定是否应该添加订单,因为它们已经可以从客户等处获取...

To sum it up, what are best practices when defining DbContext (and domain model for that matter) and should that be driven by the features (use cases) of the application? 总结一下,定义DbContext(以及域模型)的最佳实践是什么,应该由应用程序的功能(用例)驱动? Feel free to use and change code in my example above in your explanation. 在您的解释中,请在上面的示例中随意使用和更改代码。

Consider protected setters for your properties. 考虑您的属性的受保护的setter。 Otherwise you could end up with 'data entities' rather then a proper domain model. 否则,您最终可能会使用“数据实体”而不是适当的域模型。

public class Customer
{
    public string Address { get; protected set; }

    public MoveTo(string newAddress)
    {
        if (newAddress == null) throw new ArgumentNullException("newAddress");
        // and other address sanity checks..

        Address = newAddress;
        DomainEvent.Publish(new CustomerMoved(CustomerNumber, newAddress));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 EF5 Model-First,DBContext代码生成和派生类 - EF5 Model-First, DBContext code generation and derived class 在EF4.3.1代码优先迁移期间如何忽略派生的DbContext - How to ignore derived DbContext during EF4.3.1 Code First migration 如何在 DDD 中使用 EF DbContext 分离我的聚合 - How to separate my Aggregates by using EF DbContext in DDD 当我实例化从EF DbContext派生的类时会发生什么? - What happens when i instantiate a class derived from EF DbContext? 无法使用实体框架(版本4.3.1)以调试方式调试到我的DbContext派生类代码中 - cannot debug into my DbContext derived class code using Entity Framework (ver 4.3.1) code-first EF Code First DBContext和Transactions - EF Code First DBContext and Transactions EF代码优先方法中DbContext类的空构造函数的目的是什么? - What is the purpose of empty constructor of DbContext Class in EF Code First Approach? 在每种类型使用EF代码优先表的同时如何将基本类型的数据更新为派生类 - How can I update the base type's data to a derived class while using EF code first table per type C#-首先使用EF代码获取数据-DbContext - C# - Get data using EF code first - DbContext MVC4 / EF /代码优先-在派生类中实例化ICollection时,InvalidCastException - MVC4 / EF / Code First - InvalidCastException when instantiating ICollections in a derived class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM