如何最好地扩展实体框架生成的POCO对象,同时保持关系

本文关键字:对象 关系 POCO 扩展 何最好 实体 框架 | 更新日期: 2023-09-27 18:10:50

我正在做一个项目,在那里我创建了一个核心DAL/BLL与实体框架和生成POCO对象。我已经为POCO创建了部分类,以包含我想在这些基本业务对象上实现的核心功能。

解决方案将适用于多个客户端,这些客户端实现业务逻辑的方式略有不同。我希望能够扩展一些POCO对象,以添加额外/更改当前功能。我想把它和它们的核心功能分开,正如我所说的,核心功能是在偏导数中定义的。

我遇到的问题是,如果我创建一个扩展POCO对象的对象,我只能维护扩展对象和它所关联的原始POCO对象之间的关系。我需要以某种方式定义扩展POCO对象之间的关系。

一个例子是,如果我有一个客户POCO,其中包含一个订单列表,这些订单也是POCO。假设由于某种原因我需要定制Customer类,所以我创建了一个CustomCustomer类,它扩展了Customer的功能。然后由于某种原因,我需要自定义Order类,所以我创建了一个CustomOrder类,它扩展了Order的功能。如何维护CustomCustomer和CustomOrders之间的关系。

我最初认为Decorator模式可以在这里帮助我,但是当我开始实际实现它时,它似乎是相当多的工作,我只是想看看在我继续之前是否遗漏了一些明显的东西。

如何最好地扩展实体框架生成的POCO对象,同时保持关系

根据您的需要,这里有两种方法:

如果你的CustomCustomer类需要使用CustomOrder,但不是通过自定义方法(意味着你可以使用它引用Order基类型),你不需要保留那些新的引用,实体框架会为你照顾,只要你配置继承层次。

它将加载Orders列表,但其中一些实际上是CustomOrder,但在Order列表上。

另一方面,如果您确实需要使用CustomOrder,在CustomCustomer上输入CustomOrder,则在CustomCustomer上创建一个属性,过滤除自定义之外的所有Orders:

public IEnumerable<CustomOrder> CustomOrders
{
    get
    {
        return base.Orders
            // We check the BaseType here because EF creates a derived class of our classes. 
            .Where(o => o.GetType().BaseType == typeof(CustomOrder))
            .Select(o => o as CustomOrder);
    }
}

请注意,即使在第二种方法中,您也需要在EF中配置继承层次结构才能使其工作。

如果这些对你都不起作用,去硬路线:把CustomCustomerId放在CustomOrder上,在CustomCustomer上有一个单独的列表,并准备好接受这样一个事实,即如果你得到了所有包含CustomerId = 1的订单,你可能没有真正得到所有的订单…

您的POCO是不是业务对象。它们是数据对象。如果希望实现业务对象,则应该创建这些对象的业务版本,然后根据需要在数据和业务对象之间复制数据。像AutoMapper这样的工具可以帮助你。