Entity Framework 和存储库模式概念上的困难

Entity Framework and Repository Pattern conceptual difficulties

我正在使用 ASP.NET MVC 和 SQL Server 2012 创建一个内联网网站。我正在使用 Onion Architecture 创建一个存储库和架构。我的问题是我工作的公司已经有几个服务器数据库,其中 table 彼此之间没有关系。相反,有 tables 来映射这些关系。例如,一个 table 用户和一个 table 文档有一个 table User_joint_Document 来建立关系,包含两个 ID(IDDocument 和 IDUser)。现在,当我编写我的通用存储库时:

class Repository<T> : IRepository<T> where T : class 

问题是泛型类型 T 没有意义,我不能使用 EF 查询影响我的模型中的值,这是正常的,如果有一个父 class BaseEntity 到为每个 table 定义了 ID,然后我可以写:

class Repository<T> : IRepository<T> where T : BaseEntity

我所有的 table 模型都将继承自 BaseEntity。但这也意味着以关系方式重写整个数据库并手动映射每个数据库 POCO(如果我错了请纠正我),而且我没有这样做的技能(有超过 300 tables在不同的服务器数据库中,我缺乏执行此类操作的适当知识和经验)。

有没有办法在保留我原来的数据库结构的同时,仍然编写一个通用存储库?一个人会怎么做呢?

编辑 澄清我的问题,因为@saeb 部分回答了我的问题。我的 DB POCO 没有父级 class 可以拥有通用存储库吗?或者我是否需要它以便只有一个存储库来统治它们?例如:

class Repository<T>:IRepository<T> where T : class
{
  private readonly ApplicationContext context;
  private DbSet<T> entities;
  public Repository(PrincipalServerContext context)
  {
        this.context = context;
        entities = context.Set<T>();
  }
  public T Get(long id)
  {
     return entities.SingleOrDefault(s => s.IDUser == id);
     //This does not work, IDUser isn't recognized

  }

感谢您的帮助!

... has several Server DBs in which the tables have no relations between each other ...

但是他们确实有一个关系,一个Many-to-Many关系,这是通过第三个映射table定义的(无论是正确定义的关系是另外一个话题)

... the problem is the Generic type T makes no sense and I can't affect values in my model using EF queries ...

为什么不能,为什么你不能?考虑到您的 table 示例,您将有两个实体,UserDocument,它们看起来像这样:

public class User
{
    public int IDUser { get; set; }

    public virtual ICollection<Document> Documents { get; set; }

    ...
}

public class Document
{
    public int IDDocument { get; set; }

    public virtual ICollection<User> Users { get; set; }

    ...
}

并且您可以在您的上下文 OnModelCreating 中使用流利的 API 通过第三个 table:

建立关系
public class YourContext: DbContext
{
    ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasMany<Document>(u => u.Documents)
            .WithMany(d => d.Users)
            .Map(userJointDocument =>
                {
                    userJointDocument.MapLeftKey("IDUser");
                    userJointDocument.MapRightKey("IDDocument");
                    userJointDocument.ToTable("User_joint_Document");
                });
    }

    ...
}

然后您可以在存储库中查询 UserDocument,就像它们之间存在直接关系时一样。 Here are more good sources 如果愿意,可以了解更多相关信息。

据我所知,现在有一种方法可以实现这一点,而无需至少放置一个基础 class 或 entities/POCOs

的接口

您可以尝试使用表达式来实现通用存储库

public interface IEntity<T> where T : class
{
    Expression<Func<T, bool>> GetByIdPredicate(long id);
}        

public partial class User : IEntity<User>
{
   public int UserID { get; set; }

   public Expression<Func<User, bool>> GetByIdPredicate(long id)
   {
      return (User entity) => entity.UserID == id;
   }
}

class Repository<T>:IRepository<T> where T : class, IEntity, new()
{
  private readonly ApplicationContext context;
  private DbSet<T> entities;
  T dummyEntity;

  public Repository(PrincipalServerContext context)
  {
        this.context = context;
        entities = context.Set<T>();
        dummyEntity = new T();
  }
  public T Get(long id)
  {
     return entities.SingleOrDefault(dummyEntity.GetByIdPredicate(id));
  }

可能还有一种更简洁的方法也可以删除 dummyEntity 字段