如何从此DbSet中过滤出IsSoftDeleted
个项目?
var type = GetTypeFromString("Whatever");
var whatevers = Set(type);
方法
public dynamic Set(Type type)
{
var set = dbContext.Set(type);
return set;
}
模型
public class Whatever : BaseEntity
{
public virtual string Name { get; set; }
}
public class BaseEntity
{
public virtual int Id { get; set; }
public virtual bool? IsSoftDeleted { get; set; }
}
编辑:忘记显示来自Whatever
BaseEntity
答案 0 :(得分:4)
您的Whatever类没有任何IsSoftDeleted属性,因此无需过滤。我将假设从BaseEntity派生出什么。
主要问题是IQueryable< T>。实际上并不存在:它是一个扩展方法,并且扩展方法对动态类型不起作用。如果编译器可以看到类型实现IQueryable< T>,则可以键入var.Where(...)并让编译器将其解析为System.Linq.Queryable.Where(var,...)。由于该示例中的类型是动态的,因此编译器不知道它实现了IQueryable,并且当您尝试调用Where时会报告错误。
您可以将DbSet强制转换为IQueryable< BaseEntity> (只要Type有BaseEntity作为基类),并调用任何过滤器。你真的使用动态类型功能吗?如果没有,您还可以考虑删除自定义Set函数,并使用默认的DbContext.Set函数。
var query = (from e in (IQueryable<BaseEntity>)dbContext.Set(type)
where e.IsSoftDeleted != true
select e);
注意:这与不与使用dbContext.Set(type)相同.Cast&lt; BaseEntity&gt;():这不起作用,因为DbSet&lt; BaseEntity&gt;和DbSet&lt; Whatever&gt;是不相容的。只有IQueryable和其他具有“out”类型参数的接口才能执行此操作。
答案 1 :(得分:3)
问题是Set(Type type)
会返回非通用DbSet
。要应用过滤器,您必须将其强制转换为通用IQueryable<T>
:
var set = ((IQueryable<BaseEntity>)dbContext.Set(type))
.Where(be => be.IsSoftDeleted.HasValue && !be.IsSoftDeleted.Value);
仅当type
来自BaseEntity
或BaseEntity
本身时才有效,否则您将获得运行时异常。
结果set
的类型为IQueryable<BaseEntity>
,因此问题是,此结果的用途以及如何为Where(w => w.Name == "abc")
等派生实体应用更多过滤器。至少,通过制作set
类型的dynamic
,我无法获得可编译的代码。我也不想失去所有强烈的打字。