LINQ - 外键数据和表达式树

时间:2014-05-17 03:26:04

标签: c# asp.net-mvc linq

第一次发帖。如果我错过了什么,请道歉。我有一个.NET MVC程序,它接受来自用户的任意数量的过滤器,然后尝试根据这些过滤器从模型中检索数据。我在动态LINQ和表达式树方面取得了成功,但仅在评估我的父模型(Insured)上的字段时才有效。我似乎无法弄清楚如何通过LINQ正确访问子模型(引用),LINQ通过外键关系链接到Insured模型。我的db模型:

    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,用于填充View模型:

m.Insureds = (from i in repository.Insureds
              orderby i.INS_NAME
              select i).Where(GetWhere(s));

我的GetWhere函数看起来像这样(它接受不同的View模型的搜索选项):

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);

GetLob在哪里......

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))

1 个答案:

答案 0 :(得分:0)

看起来您可能需要使用&#34; let&#34;关键字c#linq支持,

这是一个例子(来自LinqPad)

  

来自产品中的p   让spanishOrders = p.OrderDetails                          .Where(o =&gt; o.Order.ShipCountry ==&#34; Spain&#34;)   其中spanishOrders.Any()   orderby p.ProductName选择新的   {
      p.ProductName,
      TotalValue = spanishOrders .Sum(o&gt; =&gt; o.UnitPrice * o.Quantity)   }