【问题标题】:Using two different data context in a LINQ JOIN Query在 LINQ JOIN 查询中使用两个不同的数据上下文
【发布时间】:2017-06-12 14:30:28
【问题描述】:

我经历了许多有关此问题的问题,并试图找到解决方案,但没有运气。所以这是我的情况:

private IQueryable<tblB> MT;
var IDs = (from z in db1.tblA
           where z.TA == User.Identity.Name
           select z).ToArray();

MT = from s in db2.tblB
     join a in IDs on s.BP equals a.BP                                  
     select new tblB() { LastName = s.LastName}); 

return View(MT.ToPagedList(pageNumber, pageSize));

我在 return 语句中遇到异常 - $exception {"无法创建类型为 'tblA' 的常量值。在此上下文中仅支持原始类型或枚举类型。"} System.NotSupportedException

当我调试 IDs 数组时,我看到它有来自 tblA 的数据,但第二次使用 join 的查询似乎不起作用。我犯了什么错误。救命!!!

【问题讨论】:

  • 您不应该使用 db1.tblA.AsEnumerable() 和 db1.tblB.AsEnumerable() 吗?

标签: c# asp.net-mvc linq


【解决方案1】:

您需要使用Contains 来生成和IN sql 子句:

首先,更改第一个查询以返回您需要的原始数据:

var IDs = (from z in db1.tblA
           where z.TA == User.Identity.Name
           select z.BP).ToArray();

然后在第二个查询中使用该内存列表:

MT = from s in db2.tblB
     where IDs.Contains(s.BP)                                
     select new tblB() { LastName = s.LastName}); 

顺便说一句,这不是 2 个上下文操作。您正在将第一个上下文中的数据加载到内存中(注意.ToArray()),然后使用这些内存中的数据来查询第二个上下文。

【讨论】:

  • 现在我在返回行{“无法在 LINQ to Entities 查询中构造实体或复杂类型 'tblB'。”}
  • @citm09 这是另一个问题。这与您的原始问题无关,这是一个答案:stackoverflow.com/a/12916245/3185569
  • 我正在创建一个新的新 tblB 对象,它给了我这个异常。一旦我删除该异常就消失了。非常感谢。我被困了几个小时,不知道该怎么办。
【解决方案2】:

因此,您希望 tblB 的所有元素的属性 BP 至少等于 IDs 中元素的 BP 属性之一。

问题是ToList() 之后IDs 在本地内存中,而您的db1.tblB 在数据库中。您必须将两个序列带到同一个平台,要么都到你的数据库,要么都到本地内存。哪个更有效取决于序列和结果的实际大小

如果要在数据库端执行查询,请使用 Contains。完整的 ID 列表将被传输到数据库,在那里执行查询并将结果传输到本地内存。

如果 ID 相当短并且您的结果几乎不是完整的tblA,请使用此方法

var result = db2.tblB
   .Where(elementOfTableB => IDs.Contains(elementOftableB);

无需创建新的 tblB 对象,显然您想要完整的 tblB 对象。

使用 AsEnumerable 如果您希望与 tblB 中的元素数量相比有很多 ID。与将完整的 tblB 传输到本地内存相比,将 ID 传输到数据库所需的时间要多得多。

db2.TblB                              // take all tblBelements
    .AsEnumerable()                   // bring to local memory
    .join(IDs,                        // join with list IDs
       tblBElement => tblBElement.BP  // take from each tblBElement the BP
       idElement => idElement.BP      // take from each ID the BP
       (tblBElement, idElement) =>    // when they match take the two records
                                      // and get  what you want. 
       tblBElement);                  // in this case the complete tblBElement

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 2011-01-20
    • 1970-01-01
    相关资源
    最近更新 更多