看下面的senario:
class CompanyDto {
public string Street { get; set;}
public int Number { get; set;}
public bool IsAttr1 { get; set;}
public bool IsAttr2 { get; set;}
public bool IsAttr3 { get; set;}
// Other not common Properties
}
class AnimalDto {
public string Street { get; set;}
public int Number { get; set;}
// Other not common Properties
}
class HouseDto {
public bool IsAttr1 { get; set;}
public bool IsAttr2 { get; set;}
public bool IsAttr3 { get; set;}
// Other not common Properties
}
class PersonDto {
public string Street { get; set;}
public int Number { get; set;}
public bool IsAttr1 { get; set;}
public bool IsAttr2 { get; set;}
public bool IsAttr3 { get; set;}
// Other not common Properties
}
我有一些要从Entinty Framework上下文中填充的Dto。我想使用标准的where子句过滤结果。
例:
List<PersonDto> prs = context.Person.Where(x => x.Number == SomeValue && Street == SomeOtherValue).Where( x=> x.IsAttr1 || x.IsAttr2).Select(//projection here).ToList();
List<AnimalDto> anmls = context.Animal.Where(x => x.Number == SomeValue && Street == SomeOtherValue).Select(//projection here).ToList();
etc.
我想将它们投影到Dtos(简单),但是我不想一次又一次地编写Where子句。我尝试使用扩展方法来执行此操作,但是在使用基类(地址和标志)和使用接口时都失败了,因为IQuerable无法从接口转换为具体类。
有什么办法可以做到吗?
最好的方法是采用这样的扩展方法:
public static IQueryable<IAddress> WhereAddress(this IQueryable<IAddress> qry, int SomeValue, int SomeOtherValue)
{
return qry.Where(x => x.Number == SomeValue && Street == SomeOtherValue);
}
但是我不能在WhereAddress子句和IQuerable.cast()之后添加WhereFlags。没做演员。
最佳答案
您可以通过以下方式实现扩展方法,并在通用参数上将约束限制为IAddress
和class
类型(这样可以避免出现“ LINQ to Entities仅支持转换EDM基本类型或枚举类型”的异常),并在您的Company
,Animal
和Person
类型
public static IQueryable<TAddress> WhereAddress<TAddress>(this IQueryable<TAddress> qry, int SomeValue, string SomeOtherValue)
where TAddress : class, IAddress {
return qry.Where(x => x.Number == SomeValue && x.Street == SomeOtherValue);
}
有了这个你可以打电话
context.Person.WhereAddress(SomeValue,SomeOtherValue).Where(x=> x.IsAttr1 || x.IsAttr2);
但不是
context.House.WhereAddress(SomeValue,SomeOtherValue);
原因
House
不实现IAddress
。