Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 默认类别Where in包括Generyc存储库实体框架6.1代码优先c#_Generics_C# 4.0_Lambda_Ef Code First_Repository Pattern - Fatal编程技术网

Generics 默认类别Where in包括Generyc存储库实体框架6.1代码优先c#

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

我有一个通用存储库,其中所有数据库表都有一个要删除的列。例如:

我需要将Sale表中存储库持有的所有查询添加到条件否定删除列中,包括包含表(SaleItem、Item、Customer)的时间

[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
{
  //
}
您需要使用此