实体框架复杂LINQ支持

时间:2011-05-29 01:32:22

标签: .net linq entity-framework entity-framework-4

我知道实体框架有一些LINQ支持问题(至少与其前身LINQ to SQL相比)......通常我能找到一种重构LINQ查询的创造性方法,以便EF支持它并且不会抛出

"Unable to create a constant value of type ..."

但这次我遇到了麻烦。像往常一样,问题与复杂的连接有关。这次需要对我正在使用的一些遗留数据进行建模。

我有办公室的查询(一个简单的POCO)

public IQueryable<Office> Offices
{
    get
    {
        IQueryable<Office> query = 
            from pn in _context.Locations
            where pn.Type == "Y"
            select new Office
            {
                Id = pn.Id  + 1000,
                Name = pn.Name,
            };

        query = query.Union(
            from r in _context.Resources
            where r.ResourceType == "L"
            select new Office
            {
                Id = r.ResourceId,
                Name = r.ResourceName,
            });

        return query;
    }
}

然后我还有其他东西上有Office属性。

public IQueryable<ScheduleEntry> ScheduleEntries
{
    get
    {
        return 
            from pc in _context.CalendarEntries
            join o in this.Offices on pc.LocationId 
                equals o.Id into offices
            from office in offices.DefaultIfEmpty()
            let mainOffice = this.Offices.First()
            select new ScheduleEntry
            {
                Id = pc.CalendarId,
                StartDateTime = pc.StartDateTime ?? DateTime.MinValue,
                EndDateTime = pc.EndDateTime ?? DateTime.MinValue,
                Office = pc.LocationId == 0 ? mainOffice : office,
            };
    }
}

请注意,告诉我让它成为可疑的目的......所以请不要这样做。

所以....正在做CalendarEntries.ToArray()投掷"Unable to create a constant value of type Office"...

具体问题是let mainOffice = Offices.First()。如果我删除该逻辑,查询工作正常。知道如何使用Entity Framework吗?

感谢。

2 个答案:

答案 0 :(得分:2)

是的,看起来像双重查询可以绊倒它。唯一的选择是离开加入办事处或执行以下操作:

       Office mainOffice = Offices.First();
       return from pc in _context.CalendarEntries
               join o in Offices on pc.LocationId equals o.Id into offices
               from office in offices.DefaultIfEmpty()
               select new ScheduleEntry
                          {
                              Id = pc.CalendarId,
                              StartDateTime = pc.StartDateTime ?? DateTime.MinValue,
                              EndDateTime = pc.EndDateTime ?? DateTime.MinValue,
                              Office = pc.LocationId == 0 ? mainOffice : office,
                          };

我假设您不想这样做,因为有关使其成为IEnumerable的投诉,因此您需要加入可查询的办事处,如何告诉EF如何将查询串在一起。设x = y或value = value正在寻找一个我觉得有意义的常数。

答案 1 :(得分:0)

First在构造表达式树时执行查询,因此它尝试将Office作为参数传递给您的查询,这是无法完成的。

替换First的一种方法是调用this.Offices.Take(1)