我有一个具有Table Per Hierarchy继承的LINQ to实体模型。我有一个基类型的查询,我想做特定的类型相关的逻辑。例如:
IQueryable<BaseType> base = ...
// this works fine
var result = base.Select(b => b is DerivedType1 ? 1 : 2).ToList();
// this doesn't compile to SQL
var result2 = base.Select(b => b is DerivedType1 ? ((DerivedType1)b).DerivedProperty : null).ToList();
有没有办法做这样的事情而不分别处理每个派生类型的IQueryables:
// I'd rather not do this:
var resultA = base.OfType<DerivedType1>().Select(d => d.DerivedProperty);
var resultB = base.OfType<DerivedType2>().Select(d => default(int?));
var result = resultA.Concat(resultB).ToList();
答案 0 :(得分:26)
LINQ-to-Entities不支持直接转换为实体类型(DerivedType1)b
,但as
运算符(b as DerivedType1
)是,因此您可以尝试:
var result2 = base
.Select(b => b is DerivedType1
? (b as DerivedType1).DerivedProperty
: null)
.ToList();
答案 1 :(得分:0)
您可以在您的派生类型中覆盖基础类型上的方法,以提供相关的属性值。
public class MyBaseClass
{
public virtual int GetSomething()
{
throw new NotImplementedException();
}
}
public class MyDerivedClass1 : MyBaseClass
{
public int SomeProperty { get; set; }
public override int GetSomething()
{
return this.SomeProperty;
}
}
public class MyDerivedClass2 : MyBaseClass
{
public int SomeOtherProperty { get; set; }
public override int GetSomething()
{
return this.SomeOtherProperty;
}
}
然后你可以:
var result = base.Select(b => b.GetSomething()).ToList();
答案 2 :(得分:0)
试试这个,我从未做过任何需要做这种事情的事情,但这应该做到。此外,如果您使用base
,首先不要因为它是关键字,但如果必须,请使用@base
名称前面的@表示它不用作关键字。< / p>
var resultA = base.Select(aVar =>
(aVar is DerivedType1) ?
(DerivedType)(((DerivedType1)aVar).DerivedProperty)
:
(DerivedType)(default(int?))
).ToList();
答案 3 :(得分:0)
OfType<DerivedType1>()
将返回一个IEnumerable,如果可能的话,尝试将基类型更改为IEnumerable而不是IQueryable,使用IQueryable时可能会遇到一些SQL限制。
当然,如果您实际上没有查询数据库,那么这是什么?
答案 4 :(得分:0)
您可以使用EntityFramework.Extended来提高查询的性能,而不是两次往返DB。
var resultA = base.OfType<DerivedType1>().Select(d => d.DerivedProperty).Future();
var resultB = base.OfType<DerivedType2>().Select(d => default(int?)).Future();
var result = resultA.Concat(resultB).ToList();
在这种情况下,只执行一次往返bd的往返。 这个框架对于很多其他的东西非常有用。