Entity Framework 和工厂模式

4

我试图使用Entity Framework实现工厂模式,但是无论它们是私有的还是公共的,Entity Framework似乎都会调用每个成员的默认构造函数和设置器。

有没有办法让Entity Framework调用我的Object.Create()呢?

编辑:
以下是我的类的简化示例。我需要Entity Framework调用静态的Create()方法而不是构造函数。

public class Foo
{
    public Name { get; set; }
    public static Foo Create()
    {
        var newFoo = new Foo();
        newFoo.Init();
        return newFoo;
    }
    public void Init()
    {
        Name = "You know, on second thought, I want the name to be this instead.";
    }
    private Foo()
    {
        Name = "Hello Stack Overflow!";
    }
}

你能展示一下你尝试过什么,以及在代码中遇到了什么错误吗? - stackunderflow
我已经添加了一个简单的例子来说明我的意思。 我正在使用static Create()Init()更改类之后返回该类的实例。 是否有一种方式可以强制Entity Framework调用Init()? - Charles W
4个回答

2

工厂应该只返回符合接口的实例,因此仅返回接口。无论实例是由EF创建(并在传递之前更改属性)还是由模拟框架创建,都不会影响工厂的使用者。


我不确定是否理解。实体框架在初始加载时不会调用“Static Foo Create()”。 - Charles W
@CharlesW,EF是从数据库中提取数据吗?如果是这样,为什么需要调用create呢?如果需要更改属性,则工厂模式将在发送之前调用“Create”;或者更改“Create”为“PostConstruction”,它位于部分类上,该部分类在EF构造后被调用。 - ΩmegaMan
@CharlesW 我认为工厂应该位于 EF 之外,并使用 EF 创建初始对象,而不是工厂驻留在 EF 实例/类中。 - ΩmegaMan

2
首先,你可以尝试搜索如何解决或实体注入IoC或类似问题 - 因为这是经常被要求的,并且基本上需要相同的解决方案。
其次,通常情况下(但不一定),你正在尝试做的事情表明设计有点笨拙,并且可能会在以后遇到问题 - 实际上,对我来说,这表明你应该寻找不同的方法。实体、POCO并不是设计用于这种方式(再次强调,这并不意味着没有情况需要它们),并且有办法解决这种使用方式。让EF创建和处理它们,并尝试将初始化提取到某种形式的存储库中。这至少是我的建议...
实体构造函数在内部被调用(无论是私有还是公共),据我所知,即使是最新的EF 6也没有提供手段。EF 6具有IDbDependencyResolver,但对你的情况没有帮助。
但你可以做的是在对象初始化过程中进行“注入” - Ladislav Mrmka 在这里 IOC with Entity Framework 中也提到了类似的情况。
你需要获取对 ObjectContext 的引用,如下所示: var objectContext = ((IObjectContextAdapter)db).ObjectContext; 然后使用 objectContext.ObjectMaterialized,其中事件的 ObjectMaterializedEventArgs 参数具有 Entity 对象。
你需要根据你的类型进行额外的转换才能得到你自己的实体。
我已经有一段时间没有使用过它了,但可能可以满足你的需求。

1
您无法在通用方法组中使用鸭子类型。并且没有所谓的静态接口。因此,如果不创建某个工厂类(而不是您的静态工厂方法)并将工厂实例传递给EF或某些资源定位器或注册表以及可能需要的所有工厂,则实际上不可能。但是,Entity Framework没有这样的可扩展性。
另一方面,如果您需要这样的控制,您可能希望在dapper之上创建自己的迷你框架。

-1

//#1 产品接口 //#2 工厂方法接口 //#3 控制器类继承自产品和方法接口,以生产您的产品
//#4 您可以使用不同的工厂方法内部程序生成尽可能多的控制器,以满足业务需求

//#5 使用您需要在数据库中记录的控制器类子集创建 EF //#6


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接