DataContext中的LINQ查询问题

时间:2012-03-13 07:34:26

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

 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是同一个datacontext CorporateCalendarDataContext中的VIEWS。 我甚至在设计师中刷新了我的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;
    }
}

1 个答案:

答案 0 :(得分:2)

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

我觉得你看起来有这个属性:

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