我正在使用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
}
感谢您的帮助!
答案 0 :(得分:3)
...有几个服务器数据库,其中表之间没有任何关系......
但是他们做有一种关系,Many-to-Many关系,这是通过第三个映射表定义的(这是否是正确定义的关系是另一个主题)
...问题是Generic类型T没有意义,我不能使用EF查询影响我的模型中的值...
为什么不呢,为什么不能呢?考虑到您的表格示例,您有两个实体,User
和Document
,它们看起来像这样:
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");
});
}
...
}
然后,您可以查询存储库中的User
和Document
,就像它们之间存在直接关系一样。如果您愿意,Here more好sources可以了解详情。
答案 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
字段