带有计算列的System.Linq.Expressions

问题描述 投票:0回答:2

在我正在工作的MVC项目中,我有一个kendo dropDownList,它调用我的服务器Action来执行任何读取操作(包括过滤):

ServiceRequestAssociabili([DataSourceRequest] DataSourceRequest request, int? idServiceRequestOriginale)

小部件绑定到 2 个属性: IdServiceRequest(值)和 IdServiceRequestDecrizione(文本)。

IdServiceRequest 是实体 Id,IdServiceRequestDesrizione 是我在实体的 Partial 类中定义的计算列

public string IdServiceRequestDescrizione
        {
            get
            {
                if (TipologiaChiamata.IdTipologiaChiamata != (int)Enums.TipologiaChiamata.Automatica)
                {
                    return IdServiceRequest + " " + Note;
                }
                else
                {
                    return IdServiceRequest + " " + Email.EmailOggetto;
                }
            }
        }

为了创建正确的 linq 查询来执行过滤器,我创建了一个 System.Linq.Expression,它将我的实体转换为包含 2 个字符串属性的 DTO:

Expression<Func<ServiceRequest, DTO>> funcError = s => new DTO
            {
                IdServiceRequest = s.IdServiceRequest,
                IdServiceRequestDescrizione = s.IdServiceRequestDescrizione
            };

然后我使用这个表达式来投影我的 IQueryable:

var srq = _serviceRequestRepository.GetByParametersAsQueryable(idServiceRequestOriginale: idServiceRequestOriginale, senzaTicketAssociato: true).Select(funcError).ToList();            

当我使用 ToList() 实现查询时,会发生以下错误:

如果我不是在部分中定义 IdServiceRequestDesrizione,而是在 System.Linq.Expression 中定义它,则不会引发任何错误,并且一切正常。

Expression<Func<ServiceRequest, DTO>> func = s => new DTO
            {
                IdServiceRequest = s.IdServiceRequest,
                IdServiceRequestDescrizione = s.TipologiaChiamata.IdTipologiaChiamata != (int)EntityModel.Enums.TipologiaChiamata.Automatica ? s.IdServiceRequest + " " + s.Note : s.IdServiceRequest + " " + s.Email.EmailOggetto
            };

有人可以给我这个行为的专业解释吗?为什么我无法在 linq 表达式中引用自定义属性?

c# asp.net-mvc entity-framework linq kendo-asp.net-mvc
2个回答
1
投票

计算列是用 C# 实现的,但 EF 仅对数据库模型进行操作(与 SQL 相互转换)。

如果您颠倒方法调用的顺序,您的代码应该可以工作

.ToList().Select(funcError);

即记录首先被转换为 C# 实体对象,然后可以访问计算列。 (我通常使用NHibernate,但问题是一样的)


0
投票

有一些选择:

1) Linq.翻译 Linq.翻译

这允许你写这样的东西:

public class Customer
{
  public string FirstName { get; set; }
  public string LastName { get; set; }

  private static readonly CompiledExpression<Customer, string> fullNameExpression
     = DefaultTranslationOf<Customer>.Property(e => e.FullName).Is(e => e.FirstName + " " + e.LastName);

  [NotMapped]
  public string FullName
  {
    get { return fullNameExpression.Evaluate(this); }
  }
}

var customers = ctx.Customers
  .Select(c => new
  {
    FullName = c.FullName
  })
  .WithTranslations();

2)DelegateDecompiler DelegateDecompiler

public class Customer
{
  public string FirstName { get; set; }
  public string LastName { get; set; }

  [NotMapped]
  [Computed]
  public string FullName
  {
    get { return FirstName + " " + LastName; }
  }
}
var customers = ctx.Customers
  .Select(c => new
  {
    FullName = c.FullName
  })
  .Decompile();
© www.soinside.com 2019 - 2024. All rights reserved.