C# EF相同,其中适用于不同的对象
看看下面的senario:C# EF相同,其中适用于不同的对象,c#,entity-framework,linq-to-entities,C#,Entity Framework,Linq To Entities,看看下面的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 P
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
}
我有这些DTO,我想从EntityFramework上下文填充它们。问题是我想用标准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.
List prs=context.Person.Where(x=>x.Number==SomeValue&&Street==SomeOtherValue)。Where(x=>x.IsAttr1 | | x.IsAttr2)。选择(//此处投影)。ToList();
列出anmls=context.Animal.Where(x=>x.Number==SomeValue&&Street==SomeOtherValue);
等
我想将它们投影到DTO(简单),但我不想一次又一次地编写Where子句。我尝试使用扩展方法来实现这一点,但在使用基类(地址和标志)和接口时都失败了,因为IQuerable不能从接口转换到具体类
我有什么办法可以做到这一点吗
更好的方法是采用如下扩展方法:
public static IQueryable<IAddress> WhereAddress(this IQueryable<IAddress> qry, int SomeValue, int SomeOtherValue)
{
return qry.Where(x => x.Number == SomeValue && Street == SomeOtherValue);
}
public static IQueryable WhereAddress(此IQueryable qry、int-SomeValue、int-SomeOtherValue)
{
返回qry.Where(x=>x.Number==SomeValue&&Street==SomeOtherValue);
}
但是我不能在whereddress子句和IQuerable.cast()之后添加where标志;无法执行强制转换。您可以按如下方式实现扩展方法,对类型为
IAddress
和class
的泛型参数进行约束(这避免了“LINQ to Entities仅支持强制转换EDM基元或枚举类型”的例外情况),并在您的类型公司上实现接口,动物
和人
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.House.WhereAddress(SomeValue,SomeOtherValue);
原因House
未实现iadress
您可以通过对类型为iadress
和class
的泛型参数进行约束来实现扩展方法(这避免了异常“LINQ to Entities仅支持强制转换EDM基元或枚举类型”)并在您的类型公司
、动物
和人
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.House.WhereAddress(SomeValue,SomeOtherValue);
原因House
不执行IAddress
类似于以下内容如何:
public IQueryable<T> GetByAddress<T>(DbContext context, int number, string street)
{
return context.Set<T>().Select<T, IAddress>(x => x.Number == SomeValue && x.Street == SomeOtherValue);
}
比如说:
public IQueryable<T> GetByAddress<T>(DbContext context, int number, string street)
{
return context.Set<T>().Select<T, IAddress>(x => x.Number == SomeValue && x.Street == SomeOtherValue);
}
您是否尝试过存储库模式?您可以将这些查询存储在存储库中。您能更清楚一点吗?存储库是EF和前端之间的一个层。这种抽象使得将查询存储为方法非常有用,以便在任何地方重用它们。这被认为是一种良好的做法。如果你问我,比扩展方法要好得多。呵呵,我知道什么是存储库,但我看不出它如何帮助我实现我想要的。我想如果我在一个存储库基类中实现Where子句的话是可以的,但不幸的是项目的设计不是由我决定的……你试过存储库模式吗?您可以将这些查询存储在存储库中。您能更清楚一点吗?存储库是EF和前端之间的一个层。这种抽象使得将查询存储为方法非常有用,以便在任何地方重用它们。这被认为是一种良好的做法。如果你问我,比扩展方法要好得多。呵呵,我知道什么是存储库,但我看不出它如何帮助我实现我想要的。如果我在存储库基类中实现Where子句,我想这是可能的,但不幸的是,项目的设计不是由我决定的……这里也有同样的问题,LINQ to Entities只支持强制转换EDM基元或枚举类型。@AthanasiosKataras我修正了我的答案。我还需要在泛型参数中包含约束类
。@Jehof这是编译的吗?我不认为EF支持隐式强制转换,即上下文。Person
不会IQueryable
很可能是DbSet
@James。我在LinqPad中尝试过这一点,在运行时没有编译错误或异常,执行返回正确的值。我找到了相同的解决方案。感谢您的帮助,如果您没有为我指出正确的方向,我将无法找到它。这里的问题相同,LINQ to Entities仅支持强制转换EDM基元或枚举类型。@AthanasiosKataras我修复了我的答案。我还需要在泛型参数中包含约束类
。@Jehof这是编译的吗?我不认为EF支持隐式强制转换,即上下文。Person
不会IQueryable
很可能是DbSet
@James。我在LinqPad中尝试过这一点,在运行时没有编译错误或异常,执行返回正确的值。我找到了相同的解决方案。谢谢你的帮助,如果你没有给我指出正确的方向,我就找不到它了。