2017-06-16 114 views
3

我正在使用ASP.NET MVC和SQL Server 2012制作一个Intranet网站。我正在使用洋葱体系结构进行存储库和架构设计。我的问题是,我所在的公司已经有几个服务器数据库,其中表格之间没有任何关系。相反,有表格来映射这些关系。例如,一个表User和一个Document 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个表而且我没有适当的知识和经验来做这种手术)。

有没有办法让我的原始数据库结构,仍然写一个通用储存库?如何去做这件事?

编辑澄清我的问题,因为@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 

    } 

感谢您的帮助!

+0

你给Users'的'和'Documents'在数据库中正确的实例的更清洁的方式。一个用户可以有许多文档,所以你需要一个'User_joint_Document'联结表。这正是应该如何构建关系数据库的结构。 – melkisadek

+1

但是,如果您使用的是洋葱体系结构,则会自动为您创建存储库,您只需在DataOnion中注册它们即可。 –

+0

@melkisadek Bah!这就是我在DB上工作的糟糕之处。我会认为你会在两张桌子之间有类似1-1的关系或者类似的东西?也许那个rel'ship是一个真正的桌子?真的不是我强大的一面。如果我用ID创建父类,那么关系表会变成什么?由于它有IDDocument和IDUser,但现在我只能从父类 –

回答

3

...在该表具有相互之间没有关系的几个服务器的DB ...

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

...问题是通用类型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; } 

    ... 
} 

而且你可以使用流利的API您的上下文的OnModelCreating建立通过第三表的关系:

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"); 
       }); 
    } 

    ... 
} 

然后,如果它们之间有直接的关系,你可以查询在你的仓库User S和Document S作为你会的。 Heremoresources了解更多关于这个,如果你喜欢。

+0

感谢您的确切答案和良好的文档。我已经这样做了,但是我的回购仍然存在问题,我无法识别这些ID。我编辑了我的问题,以显示我的回购看起来像 –

+0

不能标记你很奇怪 –

1

至于我能看到你的问题,现在有实现这一目标没有把至少一个基类或您的实体的接口/波苏斯

你可以玩弄的表达式实现一个通用的存储库的方式

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

+0

哦,这是一个非常有趣的事情。我实际上重新形成了我的问题,并在这里有另一个答案,如果你有兴趣,它都使用Expression方法打包在一个方法中:https://stackoverflow.com/questions/44591796/does-a-generic-repository-需要-A-基实体类待施加-到处/ 44592318#44592318 –