通用存储库是否需要将基础实体类应用于任何地方? [英] Does a Generic Repository need a Base Entity class to be applied everywhere?
问题描述
我正在使用ASP.NET MVC和洋葱体系结构创建一个Intranet网站.我一直在执行存储库模式,但是有一个困难.
I am creating an Intranet website with ASP.NET MVC and Onion Architecture. I have been implementing the repository pattern but I have a difficulty.
假设我有一个包含IDDocument的Document表.然后,这是我的存储库(仅一种方法):
Let's say I have a Document table with IDDocument in it. Then this is my repo(with just one method):
class Repository<T> : IRepository<T> where T : class
{
private readonly PrincipalServerContext context;
private DbSet<T> entities;
//Constructor and stuff here
public T Get(long id)
{
return entities.SingleOrDefault(s => s.IDDocument == id);//Here is my problem
}
}
问题是我不能使用它,因为T不被识别为来自文档表.解决方案是创建一个BaseEntity:
The problem is that I cannot use this since T is not recognized as being from Document table. Solution is to create a BaseEntity:
public class BaseEntity{
public int ID{get;set;}
}
然后我的文档POCO变为:
Then My Document POCO becomes:
public class Document : BaseEntity{
//Properties here
}
还有我的仓库:
class Repository<T> : IRepository<T> where T : BaseEntity
{
private readonly PrincipalServerContext context;
private DbSet<T> entities;
public T Get(long id)
{
return entities.SingleOrDefault(s => s.ID == id);//Here is my problem
}
}
但是我不希望这样做.我在通用存储库中喜欢的是,它使我不必对所有不同的表重复使用相同的代码(我有300多个).但是拥有BaseEntity也将意味着对我已经完成的工作进行大量重组. 是否可以有一个通用回购协议,您可以在没有此BaseEntity类的情况下将其应用于任何POCO?
But I don't want to do this ideally. What I like in the generic repo is that it allows me to not repeat the same code for all the different tables (I have 300+). But having a BaseEntity would also mean restructuring alot of what I have already done. Is it possible to have a Generic repo that you can apply on any POCO without this BaseEntity class?
感谢您的帮助
推荐答案
您正在呼叫第二个参数的类型为Expression<Func<T, bool>>
,因此您可以根据需要使用标识符属性来手动构建表达式.
Its second parameter has the type Expression<Func<T, bool>>
so you can build expression manually, using as identifier property as you wish.
简短示例:
public T Get(long id)
{
var idName = "ID" + typeof(T).Name; // For Document would be IDDocument
var parameter = Expression.Parameter(id.GetType());
var property = Expression.Property(parameter, idName)
var idValue = Expression.Constant(id, id.GetType());
var equal = Expression.Equal(property, idValue);
var predicate = Expression.Lambda<Func<T, bool>>(equal, parameter);
return entities.SingleOrDefault(predicate);
}
想象一下您编写了lambda函数(T obj) => obj.IdProperty == id
.
这里obj
是parameter
,并且idName
应该存储"IdProperty"
字符串.
property
表示obj.IdProperty
,idValue
表示id
的值.
equal
表示obj.IdProperty == id
,谓词表示整个表达式(T obj) => obj.IdProperty == id
.
Imagine you wrote lambda function (T obj) => obj.IdProperty == id
.
Here obj
is parameter
, and idName
should store "IdProperty"
string.
property
means obj.IdProperty
, idValue
means the value if id
.
equal
means obj.IdProperty == id
, and predicate means whole expression (T obj) => obj.IdProperty == id
.
这篇关于通用存储库是否需要将基础实体类应用于任何地方?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!