System.Linq.Expressions 有计算列
System.Linq.Expressions with computed column
在我工作的 MVC 项目中,我有一个 kendo dropDownList,它调用我的服务器 Action 来执行任何读取操作(包括过滤):
ServiceRequestAssociabili([DataSourceRequest] DataSourceRequest request, int? idServiceRequestOriginale)
小部件绑定到 2 个属性:
IdServiceRequest(值)和 IdServiceRequestDescrizione(文本)。
IdServiceRequest 是实体 ID,IdServiceRequestDescrizione 是我在实体 class 的部分
中定义的计算列
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() 实现查询时,出现以下错误:
如果我不是在部分中定义 IdServiceRequestDescrizione,而是在 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#实现的,但是EF只对数据库模型进行操作(转to/from SQL)
如果您颠倒方法调用的顺序,您的代码应该可以工作
.ToList().Select(funcError);
即记录首先被翻译成 C# 实体对象,然后计算列就可以访问了。 (我一般用NHibernate,但问题是一样的)
有一些选择:
1) Linq.Tranlations Linq.Tranlations
它允许你这样写:
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
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();
在我工作的 MVC 项目中,我有一个 kendo dropDownList,它调用我的服务器 Action 来执行任何读取操作(包括过滤):
ServiceRequestAssociabili([DataSourceRequest] DataSourceRequest request, int? idServiceRequestOriginale)
小部件绑定到 2 个属性: IdServiceRequest(值)和 IdServiceRequestDescrizione(文本)。
IdServiceRequest 是实体 ID,IdServiceRequestDescrizione 是我在实体 class 的部分
中定义的计算列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() 实现查询时,出现以下错误:
如果我不是在部分中定义 IdServiceRequestDescrizione,而是在 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#实现的,但是EF只对数据库模型进行操作(转to/from SQL)
如果您颠倒方法调用的顺序,您的代码应该可以工作
.ToList().Select(funcError);
即记录首先被翻译成 C# 实体对象,然后计算列就可以访问了。 (我一般用NHibernate,但问题是一样的)
有一些选择:
1) Linq.Tranlations Linq.Tranlations
它允许你这样写:
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
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();