实体框架和存储库模式的概念上的困难

时间:2017-06-16 09:53:16

标签: c# entity-framework repository-pattern onion-architecture

我正在使用ASP.NET MVC和SQL Server 2012创建一个Intranet网站。我正在建立一个存储库并使用洋葱架构进行架构。我的问题是,我工作的公司已经有几个服务器数据库,其中表之间没有任何关系。相反,有表格来映射这些关系。例如,表User和表Document有一个表User_joint_Document来建立关系,包含两个ID(IDDocument和IDUser)。现在,当我编写我的通用存储库时:

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

问题是泛型类型T没有意义,我不能使用正常的EF查询影响我的模型中的值,最好的是让父类BaseEntity为ID定义每个表,然后我可以写:

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

我的所有表模型都将继承BaseEntity。但这也意味着以关系方式重写整个数据库并手动映射每个数据库POCO(如果我错了,请纠正我),而我没有相应的技能组合(不同的表中有300多个表)服务器DB和我缺乏适当的知识和经验来做这种操作)。

有没有办法保留我原来的数据库结构,还是写一个通用存储库?怎么会这样做呢?

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

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

  }

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

  

...有几个服务器数据库,其中表之间没有任何关系......

但是他们有一种关系,Many-to-Many关系,这是通过第三个映射表定义的(这是否是正确定义的关系是另一个主题)

  

...问题是Generic类型T没有意义,我不能使用EF查询影响我的模型中的值...

为什么不呢,为什么不能呢?考虑到您的表格示例,您有两个实体,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通过第三个表格设置关系:

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 moresources可以了解详情。

答案 1 :(得分:1)

就我看到你的问题而言,现在有办法实现这一点,而不至少为你的实体/ POCO提供基类或接口

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

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字段