Generics 默认类别Where in包括Generyc存储库实体框架6.1代码优先c#
我有一个通用存储库,其中所有数据库表都有一个要删除的列。例如: 我需要将Sale表中存储库持有的所有查询添加到条件否定删除列中,包括包含表(SaleItem、Item、Customer)的时间Generics 默认类别Where in包括Generyc存储库实体框架6.1代码优先c#,generics,c#-4.0,lambda,ef-code-first,repository-pattern,Generics,C# 4.0,Lambda,Ef Code First,Repository Pattern,我有一个通用存储库,其中所有数据库表都有一个要删除的列。例如: 我需要将Sale表中存储库持有的所有查询添加到条件否定删除列中,包括包含表(SaleItem、Item、Customer)的时间 [Table("Sale")] public partial class Sale { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsI
[Table("Sale")]
public partial class Sale
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Sale()
{
SaleItems = new HashSet<SaleItem>();
}
public long ID { get; set; }
public long? CostumerID { get; set; }
public virtual Costumer Costumer { get; set; }
public bool Deleted { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SaleItem> SaleItems { get; set; }
public class SaleRepository : BaseRepository<Sale>
{
public async Task<Sale> FindOneAndRelatedAsync(object id)
{
return await FindAsync(id,
(s => s.Costumer),
(s => s.SaleItems),
(s => s.SaleItems.Select(si => si.Item))
);
}
public class BaseRepository<T> : IBaseRepository<T> where T : class
{
private string deletedName = "Deleted";
public async virtual Task<T> FindAsync(object id, params Expression<Func<T, object>>[] includes)
{
return await FindAsync(id, false, includes);
}
public async virtual Task<T> FindAsync(object id, bool hasDeleted = false, params Expression<Func<T, object>>[] includes)
{
var query = DbSet.AsQueryable();
query = includeRelationships(includes, query);
query = query.Where(idPredicateExpression(id));
if (!hasDeleted)
query = query.Where(deletedPredicateExpression());
return await query.FirstOrDefaultAsync();
}
protected Expression<Func<T, bool>> deletedPredicateExpression()
{
return columnPredicateExpression(deletedName, false);
}
protected Expression<Func<T, bool>> columnPredicateExpression(string columnName, object keyword)
{
var arg = Expression.Parameter(typeof(T), "p");
var method = keyword.GetType() == typeof(string) ? typeof(string).GetMethod("Contains", new[] { typeof(string) }) : keyword.GetType().GetMethod("Equals", new[] { keyword.GetType() });
var body = Expression.Call(
Expression.Property(arg, columnName),
method,
Expression.Constant(keyword));
return Expression.Lambda<Func<T, bool>>(body, arg);
}
protected IQueryable<T> includeRelationships(Expression<Func<T, object>>[] includes, IQueryable<T> query)
{
if (includes != null)
{
query = includes.Aggregate(query, (current, include) => current.Include(include));
}
return query;
}
[表(“销售”)]
公共部分类销售
{
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2214:DoNotCallOverridableMethodsInConstructors”)]
公开发售()
{
SaleItems=newhashset();
}
公共长ID{get;set;}
公共长时间{get;set;}
公共虚拟客户{get;set;}
公共bool已删除{get;set;}
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2227:CollectionPropertiesShouldBreadOnly”)]
公共虚拟ICollection项目{get;set;}
公共类存储库:BaseRepository
{
公共异步任务FindOneAndRelatedAsync(对象id)
{
返回等待FindAsync(id,
(s=>s.Customer),
(s=>s.SaleItems),
(s=>s.SaleItems.Select(si=>si.Item))
);
}
公共类BaseRepository:IBaseRepository,其中T:class
{
私有字符串deletedName=“已删除”;
公共异步虚拟任务FindAsync(对象id,参数表达式[]包含)
{
返回等待FindAsync(id,false,includes);
}
公共异步虚拟任务FindAsync(对象id,bool hasDeleted=false,参数表达式[]包含)
{
var query=DbSet.AsQueryable();
查询=包含关系(包括,查询);
query=query.Where(idpreditateexpression(id));
如果(!已删除)
query=query.Where(deletedPredicateExpression());
返回wait query.FirstOrDefaultAsync();
}
受保护的表达式deletedPredicateExpression()
{
返回columnPredicateExpression(deletedName,false);
}
受保护的表达式columnPredicateExpression(字符串columnName,对象关键字)
{
var arg=表达式参数(类型(T),“p”);
var method=keyword.GetType()==typeof(string)?typeof(string).GetMethod(“包含”,新[]{typeof(string)}):keyword.GetType().GetMethod(“等于”,新[]{keyword.GetType()});
var body=Expression.Call(
Expression.Property(arg,columnName),
方法,,
常量(关键字));
返回表达式.Lambda(body,arg);
}
受保护的IQueryable includeRelationships(表达式[]包含,IQueryable查询)
{
如果(包括!=null)
{
query=includes.Aggregate(query,(current,include)=>current.include(include));
}
返回查询;
}
从上面的代码中可以看出,我可以创建一个表达式来添加条件,其中使用deletedPredicateExpression()方法的销售实体中的某个实体工作得很好。但是includeRelationships()方法(SaleItem、Item和Customer)包含的实体必须包含以下条件:
当关系为1:n时,作为客户实体。我可以执行下面的插入代码
protected IQueryable<T> includeRelationships(Expression<Func<T, object>>[] includes, IQueryable<T> query)
{
if (includes != null)
{
int i = 0;
query = includes.Aggregate(query, (current, include) => current.Include(include));
foreach (var include in includes)
{
var test = test(include.Body.Type);
query = query.Where(test).AsQueryable();
}
}
return query;
}
protected Expression<Func<T, bool>> test(Type typeEntity)
{
string columnName = typeEntity.Name +"." + deletedName;
string[] props = columnName.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "m");
Expression expr = arg;
foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
var val1 = Expression.Constant(false);
Expression e1 = Expression.Equal(expr, val1);
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
return (Expression<Func<T, bool>>)Expression.Lambda(delegateType, e1, arg);
}
受保护的IQueryable includeRelationships(表达式[]包含,IQueryable查询)
{
如果(包括!=null)
{
int i=0;
query=includes.Aggregate(query,(current,include)=>current.include(include));
foreach(包含在包含中的var)
{
var测试=测试(包括.Body.Type);
query=query.Where(test).AsQueryable();
}
}
返回查询;
}
受保护的表达式测试(类型typeEntity)
{
字符串columnName=typeEntity.Name+“+deletedName;
string[]props=columnName.Split('.');
类型=类型(T);
ParameterExpression arg=表达式参数(类型“m”);
表达式expr=arg;
foreach(道具中的字符串道具)
{
//使用反射(非组件模型)镜像LINQ
PropertyInfo pi=type.GetProperty(prop);
expr=Expression.Property(expr,pi);
type=pi.PropertyType;
}
var val1=表达式常数(false);
表达式e1=表达式.Equal(expr,val1);
Type delegateType=typeof(Func)。MakeGenericType(typeof(T),Type);
return(Expression)Expression.Lambda(delegateType,e1,arg);
}
如果我的关系为N:N,或者当我需要访问集合中的对象时,例如在实体中,SaleItems下面的项不能包含WHERE子句,因为它没有删除对象SaleItems或Item的属性
是否存在一种筛选所有实体的方法,以便在默认情况下始终根据删除==0的条件生成查询?创建一个包含Delete status属性的基本实体。然后,从该基本实体继承所有类。因此,您可以使用
WHERE
在任何位置进行筛选
public abstract class BaseEntity
{
public BaseEntity()
{
IsDelete = false;
}
[Key]
public int Id { get; set; }
public bool IsDelete { get; set; }
}
public class Yourclass : BaseEntity // Sale class or somethingelse
{
//
}
对于泛型T类,您需要使用这个BaseEntity
类作为主类,而不是class
public class BaseRepository<T> : IBaseRepository<T> where T : BaseEntity
{
public T GetById(int id)
{
return this.Entities.Single(item => item.Id == id && !item.IsDelete);
}
// implement your methods here by using IsDelete property in `Where` condition.
}
public类BaseRepository:IBaseRepository其中T:BaseEntity
{
公共T GetById(int-id)
{
返回this.Entities.Single(item=>item.Id==Id&&!item.IsDelete);
}
//通过在“Where”条件中使用IsDelete属性在此处实现您的方法。
}
使用此
BaseEntity
作为主实体类,您可以按删除状态筛选所有类,即使在集合中也是如此。创建一个包含删除状态属性的基本实体。然后,从该基本实体继承您的所有类。因此,您可以使用Where
在任何位置进行筛选
public abstract class BaseEntity
{
public BaseEntity()
{
IsDelete = false;
}
[Key]
public int Id { get; set; }
public bool IsDelete { get; set; }
}
public class Yourclass : BaseEntity // Sale class or somethingelse
{
//
}
您需要使用此