外键数据和表达式树
本文关键字:表达式 数据 | 更新日期: 2023-09-27 18:03:41
首次发布。如果我错过了什么,很抱歉。我有一个. net MVC程序,它接受来自用户的任意数量的过滤器,然后尝试基于这些过滤器从模型检索数据。我已经成功地使用了动态LINQ和表达式树,但只有在评估父模型(已投保)上的字段时才成功。我似乎不知道如何通过LINQ正确访问子模型(引用),它通过外键关系链接到被保险模型。我的数据库模型:
public class Insured {
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long INS_CLIENT_ID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string INS_AGENT_ID { get; set; }
[Key]
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long INS_UNQ_ID { get; set; }
[Column("INS_NAME")]
public string INS_NAME { get; set; }
[ForeignKey("QTE_CLIENT_ID, QTE_AGENT_ID, QTE_INS_UNQ_ID")]
public virtual ICollection<Quote> TBL_QTE { get; set; }
}
public class Quote {
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long QTE_CLIENT_ID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string QTE_AGENT_ID { get; set; }
[Key]
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long QTE_INS_UNQ_ID { get; set; }
[Key]
[Column(Order = 3)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long QTE_NUMBER { get; set; }
[Column("QTE_LOB")]
public string QTE_LOB { get; set; }
[Column("QTE_CO_CODE")]
public string QTE_CO_CODE { get; set; }
}
然后我有一个LINQ在我的控制器文件填充视图模型:
m.Insureds = (from i in repository.Insureds
orderby i.INS_NAME
select i).Where(GetWhere(s));
和我的GetWhere函数看起来像这样(它接受一个不同的视图模型的搜索选项):
private Expression<Func<Insured, bool>> GetWhere(SearchOptions s) {
ParameterExpression pe = Expression.Parameter(typeof(Insured));
Expression left = Expression.Call(Expression.PropertyOrField(pe, "INS_AGENT_ID"), "ToUpper", null);
Expression right = Expression.Constant(s.AgentId.ToUpper());
Expression e1 = Expression.Equal(left, right);
return Expression.Lambda<Func<Insured, bool>>(e1, pe);
}
这一切都很好。我只是不能扩展它来查询TBL_QTE字段。我试过…
m.Insureds = (from i in repository.Insureds
where i.TBL_QTE.AsQueryable<Quote>().All<Quote>(GetLob(s))
orderby i.INS_NAME
select i);
where GetLob is…
private Expression<Func<Quote, bool>> GetLob(SearchOptions s) {
ParameterExpression pe = Expression.Parameter(typeof(Quote));
Expression left = Expression.Call(Expression.PropertyOrField(pe, "QTE_LOB"), "ToUpper", null);
Expression right = Expression.Constant(s.LOBCode.ToUpper());
Expression e1 = Expression.Equal(left, right);
return Expression.Lambda<Func<Quote, bool>>(e1, pe);
}
…但这也不完全正确,因为Where在等待Expression。Lambda结果,而不是调用它。我只是不知道如何通过表达式树模拟导航到TBL_QTE属性。我的直觉告诉我,我接近这一行,但只是不完全在那里,因为它产生一个1025数据提供者错误:
i.TBL_QTE.AsQueryable<Quote>().All<Quote>(GetLob(s))
看起来你可能需要使用c# linq支持的"let"关键字,
下面是一个例子(来自LinqPad)
来自product中的plet spanishOrders = p.OrderDetails.Where (o => o. order . shipcountry == "Spain")在spanishOrders.Any ()order . productname选择new{
p.ProductName,
TotalValue = spanishOrders。合计(0> => 0 .单价* 0 .数量)}