【问题标题】:Linq "join" with a IList<T> getting "Error Unable to create a constant value.."Linq“加入”与 IList<T> 得到“错误无法创建常量值..”
【发布时间】:2017-09-21 22:15:24
【问题描述】:

我有一个保存方法,它通过 Linq 查询保存一个手动重新排序的列表(在网络表单中),作为参数传递给我的方法,我尝试使用列表中的相应值更新我从数据库 (EF) 检索到的IEnumerable&lt;VM_CategoryLabel&gt;Order 属性(下面的代码可能会更清楚):

public static void SaveFromList(IList<VM_CategoryLabelExtra> listTemplate)
    {
        int idCat = listTemplate.Select(x => x.IdCat).FirstOrDefault();
        var test = (int)listTemplate.Where(z => z.Id == 8).Select(z => z.Order).FirstOrDefault();

        using (var context = new my_Entities())
        {
            var requete = from x in context.arc_CatLabel
                          where x.ID_Categorie == idCat
                          orderby x.Sequence_Cat
                          select new VM_CategoryLabel
                          {
                              Id = x.ID_LabelPerso,
                              //Order = x.Sequence_Cat,
                              Order = (int)listTemplate.Where(z => z.Id == x.ID_LabelPerso).Select(z => z.Order).First(),
                              Label = x.arc_Label.Label,
                              Unit = x.arc_Label.Unit
                          };
            context.SaveChanges();
        }
    }

我使用 "test" var 来查看我的“子查询”是否获得了正确的值,并且确实如此,但是当我在 Select 中使用 Linq 表达式时(注释的 Order 行),我收到以下错误:

无法创建“Namespace.Models.VM_CategoryLabelExtra”类型的常量值。 "在此上下文中仅支持原始类型和枚举类型。

这是我的课程:

       public class VM_CategoryLabel
{
    public int Id { get; set; }
    public int Order { get; set; }
    public string Label { get; set; }
    public string Unit { get; set; }
    public bool Checked { get; set; }
}

public class VM_CategoryLabelExtra
{
    public int Id { get; set; }
    public int IdCat { get; set; }      
    public int Order { get; set; }
    public string Label { get; set; }
    public string Unit { get; set; }
    public bool Checked { get; set; }
}

所以我想我不应该在我的查询中查询列表?那么如何“匹配”这两个值列表呢?

我还尝试了以下方法(在 Linq 查询中替换后:Order = x.Sequence_Cat),因为迭代变量是 只读:

foreach (var item in requete)
                {
                    item.Order = listTemplate.Where(x => x.Id == item.Id).Select(x => x.Order).FirstOrDefault();
                }

                try
                {
                    context.SaveChanges();

【问题讨论】:

  • 我无法理解这个“Order = (int)listTemplate.Where”和 Order = x.Sequence_Cat?你不能使用两次
  • 当我取消注释第二个“订单”时,我评论了第一个(实际在数据库中获取值)。所以我在查询中只使用 1 个订单:)
  • @Bro 我喜欢你的头像/图片。真的是你吗?
  • @Elvin 我尝试了你的建议,我得到了同样的错误信息

标签: c# linq entity-framework lambda


【解决方案1】:

我建议使用this

这是let 子句。

public static void SaveFromList(IList<VM_CategoryLabelExtra> listTemplate)
    {
        int idCat = listTemplate.Select(x => x.IdCat).FirstOrDefault();
        var test = (int)listTemplate.Where(z => z.Id == 8).Select(z => z.Order).FirstOrDefault();

    using (var context = new my_Entities())
    {
        var requete = from x in context.arc_CatLabel
                      where x.ID_Categorie == idCat
                      orderby x.Sequence_Cat
                      let list = listTemplate                                     
                      select new VM_CategoryLabel
                      {
                          Id = x.ID_LabelPerso,                              
                          Order = list.Where(z => z.Id == x.ID_LabelPerso).Select(z => z.Order).First(),                             
                          Label = x.arc_Label.Label,
                          Unit = x.arc_Label.Unit
                      };
        context.SaveChanges();
    }
}

编辑:而不是from 你可以这样做 let list = listTemplate

现在应该可以工作了:)

【讨论】:

  • Pim,我试过了,VS 说上下文中不存在列表(在 list.Where... 行上)
  • 再试一次我忘了在let的末尾选择
  • 同上。我更新了错误信息(完整翻译),好像不允许执行包含的查询(list.Where...)
  • 只要我在查询中包含“let list = from q in listTemplate select q”(即使我在“Order = list...”中不使用“list”)我得到了错误。
【解决方案2】:

让的例子:

// The let keyword in query expressions comes in useful with subqueries: it lets
// you re-use the subquery in the projection:

from c in Customers
let highValuePurchases = c.Purchases.Where (p => p.Price > 1000)
where highValuePurchases.Any()
select new
{
    c.Name,
    highValuePurchases
}

如果您不知道 Let 的工作原理,请下载 LinqPad 并查看示例

【讨论】:

  • 似乎 let 子句是为了“存储子表达式的结果,以便在后续子句中使用”,但这里不是这样吗?
  • 您可以使用子查询中的结果查看此示例:link
  • 让 list = list.Where(z => z.Id == x.ID_LabelPerso).Select(z => z.Order).First(), ---> 在下面的查询中.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多