基于接口生成的表达式

Dav*_*ghi 4 c# lambda code-reuse entity-framework

收到异常 无法将类型“MySomeTypeThatImplementsISomeInterfaceAndIsPassedAs[T]ToTheClass”转换为类型“ISomeInterface”。LINQ to Entities 仅支持强制转换实体数据模型基元类型。

我的存储库看起来像

public interface IRepository<T>
{
    IQueryable<T> Get(System.Linq.Expressions.Expression<System.Func<T, bool>> Query);
}
Run Code Online (Sandbox Code Playgroud)

另外,我有服务类

public abstract class FinanceServiceBase<TAccount, TParcel, TPayment>
    where TAccount : IAccount
    where TParcel : IParcel
    where TPayment : IPayment
 {
     //...
     IRepository<TPayment> ParcelRepository {get; private set;}         

     public bool MakePayment(TPayment payment)
     {
         //...
         ParcelRepository.Get(p => p.ParcelId == 2);
         // here my exception is thrown
         // **p.ParcelId is in IParcel**
         //...
     }
 }
 //...
Run Code Online (Sandbox Code Playgroud)

有了这门课,我可以控制很多关于财务的事情,而无需为其他程序重写代码。我用 3 个泛型参数做了这个类,因为我不能使用 IRepository 因为我的存储库不能<out T>

ParcelId 是 Int32
TParcel 是 typeof( ParcelToReceive ) 这是一个实现IParcel的实体,并且是用代码生成的

当我调用 Get 时出现问题,结果 lambda 看起来像

(**(ISomeInterface)**$p).SomeInterfaceMember == 
Run Code Online (Sandbox Code Playgroud)

代替

($p.SomeInterfaceMember)
Run Code Online (Sandbox Code Playgroud)

因此,实体框架尝试进行强制转换并抛出异常。我想知道的是:无论如何要告诉 linq lambda 字段 p.ParcelId 来自TParcel而不是来自IParcel

已经尝试过(没有运气):

p => ((TParcel)p).ParcelId 
Run Code Online (Sandbox Code Playgroud)

谢谢

Dav*_*ghi 5

似乎将通用约束设置为where TAccount : IAccount类似于where TAccount : class, IAccount告诉实体框架表达式包含一个类,并且它不会对原始 EDM 和枚举类型进行显式转换。