0

我正在尝试构建允许查询域类的通用存储库。针对域类的查询应针对实体解析

我的仓库界面看起来如下:

public interface IRepository<T> 
{ 
    T Get(int id); 
    IQueryable<T> Query(); 
    void Add(T model); 
    void Remove(T model); 
} 

假设我有一个UserEntity实体框架类和User域类,我想查询对UserUserEntity不应该暴露给其他服务,因为它应该在Entity Framework层内部。

userRepository.Query().Single(user => user.UserName == "Toni")这样的查询应返回User域类。但是在内部它应该查询从我的实体框架返回的IDbSet<UserEntity>。表达式树(包含Single查询操作)应附加到针对IDbSet<UserEntity>的查询中。在查询IDbSet<UserEntity>后,我想将UserEntity转换为User域类。这可能吗?

我记得要为我的User类实施一个IQueryable实现,该类对内部查询UserEntity

public class MappedEntityQuery<TModel, TEntity> : IQueryable<TModel> 
{ 
} 
+0

'UserEntity'(POCO)应该是你的域名类。你所要做的可以被定义为在ORM之上构建ORM。 –

+0

问题是实体框架要求所有实体都驻留在同一个项目中。我试图通过为每个模块创建项目来模块化我的ASP.NET MVC应用程序。因此,我希望模块的域类能够驻留在单个项目中,这对于EF来说是不可能的。 – Toni

+0

为什么不可能? –

回答

1

代码首先要求公约都IDbSet属性来访问表是在的DbContext

这是不正确的。如果您向模型构建器中的实体提供映射,则不需要在上下文中声明任何集合。在你的情况下,你应该通过EntityTypeConfiguration<T>ComplexTypeConfiguration<T>派生类声明映射。您可以通过在上下文中调用Set<T>()来创建映射实体类型的任何DbSet实例。

然而,对于这个项目我使用一个数据库优先的做法,这也不允许加载使用来自不同项目的实体的DbContext组成,因为你必须在一个单一的元数据文件来指定数据库的元数据(这将被嵌入)。

这是真的只有部分。 EDMX元数据必须位于主项目中嵌入的单个文件中,但如果您使用自己生成的而不是自己生成的实体类,则不需要这样做。所以你提出的方法应该可行。

但是,如果你真的想实现模块化,你不应该使用EDMX。如果您决定在将来添加或更改任何模块,则需要更改中央项目,但这会影响所有其他模块 - 它打破了模块化的想法,不是吗?

+0

感谢您的深入解释!我认为Model First和Database First都需要一个数据库,并且Code First不能与现有的数据库一起使用。因此我认为我不能使用'EntityTypeConfiguration '和'ComplexTypeConfiguration '。战略如何调用(所以我可以更深入地使用Google) – Toni

+0

我开始使用驻留在单个数据层项目中的单个* .edmx文件实现Database First模型。然后我开始把实体类放在其他项目中。我了解到,您必须确保名称空间和类型名称必须匹配,并且所有属性(包括导航属性)必须存在于实体类中。否则就会抛出一个异常,无法找到实体(这导致我认为这种违规行为不会起作用)。 – Toni

+0

不幸的是,这种方法称为代码优先,但不是创建一个新的数据库,而是使用现有的数据库(您只需要通过将初始化设置为空来关闭生成功能)。 –