0

我是 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; }
}

定义域后,下一步是创建 DbContext 派生类,我的问题是它应该是什么样子?什么是上下文类定义驱动的?是通过最终应用程序的用例吗?

例如,查看上面的域,我们可以看到给定 Customer 实例,我们可以访问任何子对象。那么是否足以使上下文类仅包含 Customers 属性如下所示:

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

有了这个,我可以从我的应用程序中浏览客户,然后选择一个来查看详细信息和订单历史记录等......现在看起来不错。

现在假设我想要在我的应用程序中使用以下功能: - 列出商店中的最后 10 个订单(无论客户是谁) - 列出其中包含特定产品的所有订单

我想这些数据可以从当前上下文中提取,对吧?例如。最后 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();
        }

并获取所有包含 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();

        }

(注意我没有测试这些查询,所以不确定它们是否有效,但它们描述了我的总体想法)

所以我想这会起作用,但我想知道这是正确的道路。查询在这里会变得非常复杂,如果我将订单和产品添加到 DbContext 中可能会更容易: public class MyContext : DbContext { public DbSet Customers { get; 放; } 公共 DbSet 订单 { 获取;放; } 公共 DbSet 产品 { 获取;放; } }

另一方面,我不确定是否应该添加订单,因为它们已经可以从客户等处检索到......

总而言之,在定义 DbContext(以及与此相关的域模型)时,哪些最佳实践是由应用程序的特性(用例)驱动的?在您的解释中,请随意使用和更改我上面示例中的代码。

4

1 回答 1

2

考虑为您的属性设置受保护的设置器。否则,您最终可能会得到“数据实体”,而不是正确的域模型。

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));
    }
}
于 2013-05-27T19:15:52.320 回答