【问题标题】:LINQ query issue in DataContextDataContext 中的 LINQ 查询问题
【发布时间】:2012-03-13 07:34:26
【问题描述】:
 var activecommcontacts = 
   CorporateCalendarDataContext.ActiveCommunicationContacts.Where(p=>systemUserMinistries.Contains(p.MinistryId)).Select(p => p);                                  
    var distinctcomm = 
   CorporateCalendarDataContext.ActiveDistinctCommunicationContacts.Select(r => r);        

    IQueryable<ActiveDistinctCommunicationContact> options   
             = (from orig in distinctcomm   
                      let userid = orig.SystemUserId   
                      let name = orig.Name   
                      let nameandnumber = orig.NameAndNumber   
                      from b in activecommcontacts   
                      let actuserid = b.SystemUserId  
                      where userid == actuserid  
                      select new ActiveDistinctCommunicationContact  
                                 {  
                                     Name = name,  
                                     SystemUserId = userid,  
                                     NameAndNumber = nameandnumber  
                                 }).AsQueryable();        

我收到带有消息的 SystemInvalidOperationException
“查询包含对在不同数据上下文中定义的项目的引用。”

我什至试图通过这种方式解决它:

IQueryable<ActiveDistinctCommunicationContact> options = 
(from distinctcomm in CorporateCalendarDataContext.ActiveDistinctCommunicationContacts
 from activecommcontacts in activecommcontacts
 where activecommcontacts.SystemUserId == distinctcomm .SystemUserId
 select new 
    { 
        distinctcomm .SystemUserId, 
        distinctcomm .Name, 
        distinctcomm.NameAndNumber 
    }).AsQueryable();                                      

我收到带有消息的 SystemInvalidOperationException

“查询包含对在不同数据上下文中定义的项目的引用。”

我想指出 ActiveDistinctCommunicationContact 和 ActiveCommunicationContact 是同一数据上下文 CorporateCalendarDataContext 中的视图。
我什至在设计器中刷新了我的 DBML。
但我不断收到这个烦人的异常“查询包含对不同数据上下文中项目的引用”。我不明白为什么当视图属于相同的数据上下文时会发生这种情况。我在 stackoverflow.com 上解决了其中一些问题,但我无法让这个查询正常工作。你能帮忙吗?

public List<int> GetSystemUserMinistryList() {
    var dc = new CorporateCalendar.Data.CorporateCalendarDataContext(); //"param1", "param2", "param3");
    List<int> userMinistries = new List<int>();
    var systemUserMinistries = dc.GetTable<CorporateCalendar.Data.ActiveSystemUserMinistry>();
    foreach (CorporateCalendar.Data.ActiveSystemUserMinistry activeSystemUserMinistry in systemUserMinistries) { 
        if (activeSystemUserMinistry.SystemUserId == this.Id) {
            userMinistries.Add(activeSystemUserMinistry.MinistryId);
        }
    }

    return userMinistries;
}

private static CorporateCalendarDataContext CorporateCalendarDataContext {
    get { 
        var dc = new CorporateCalendarDataContext(); //"param1", "param2", "param3");
        return dc;
    }
}

【问题讨论】:

  • 第一:正确格式化您的问题。第二:异常意味着您持有从不同上下文实例中提取的对象,不一定是不同的内容类型。您是否持有超出上下文范围的对象?
  • 我没有持有来自不同上下文实例的对象。我需要使用相同数据上下文的两个实例,因为每个实例都引用 DBML 中的不同视图。
  • systemUserMinistries 是在哪里定义的?那是使用其他上下文吗?如果是这样,我会理解这个错误。
  • 私有静态 CorporateCalendarDataContext CorporateCalendarDataContext { get { var dc = new CorporateCalendarDataContext(); //"param1", "param2", "param3");返回直流; } }
  • 我已经添加了您要求更多详细信息的其他方法。谢谢。

标签: .net linq linq-to-sql .net-4.0 linq-to-objects


【解决方案1】:

如果我正确理解了您的问题并更新了...

我认为您似乎拥有该财产:

private static CorporateCalendarDataContext CorporateCalendarDataContext {
    get {
        var dc = new CorporateCalendarDataContext(); //"param1", "param2", "param3");
        return dc;
    }
}

所以每次获得该属性时,您都会创建一个新的上下文实例,即使这两行例如:

var activecommcontacts = CorporateCalendarDataContext.ActiveCommunicationContacts.Where(p=>systemUserMinistries.Contains(p.MinistryId)).Select(p => p);                                  
var distinctcomm = CorporateCalendarDataContext.ActiveDistinctCommunicationContacts.Select(r => r);  

使用相同的属性,它们将具有不同的上下文,因此您会看到异常。

您需要将上下文保留的时间比您现在做的要长,要么这样做:

var context = CorporateCalendarDataContext;
var activecommcontacts = context.ActiveCommunicationContacts.Where(p=>systemUserMinistries.Contains(p.MinistryId)).Select(p => p);                                  
var distinctcomm = context.ActiveDistinctCommunicationContacts.Select(r => r);  
// This context should be used for anything that you want to join together in the same query ...      

或者使该属性在创建上下文后存储它,如下所示:

private static CorporateCalendarDataContext _context;
private static CorporateCalendarDataContext CorporateCalendarDataContext {
    get {
        if(_context == null)
            _context = new CorporateCalendarDataContext(); //"param1", "param2", "param3");
        return _context;
    }
}

任何你觉得更快乐并且适合你的应用程序设计的东西。

不过,我担心它是一个静态属性,因此如果您将上下文保留太久,最后一种方法可能会给您带来额外的问题。

您需要小心数据上下文及其生命周期,因为它们很棘手,但有很多关于它们的信息。看看这篇博客文章,例如:Entity Framework Context Lifetime Best Practices 和这篇文章:How to decide on a lifetime for your objectcontext

【讨论】:

  • 我喜欢你的回答。我确实发现了问题,因为我在调用执行上述代码的方法之前禁用了调用的上下文。正如你提到的,这不是这两个数据上下文。但是你在来电者中看不到的那个。我什至不认为这是一个问题,当你在你之前的信息中睁开我怀疑的眼睛时。谢谢你的回答是最接近的。
  • 没问题 - 很高兴您发现了问题! LINQ 的整个延迟执行有时会让人很难准确地找出问题的根本原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2011-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多