Entity Framework Complex LINQ Support

蹲街弑〆低调 提交于 2019-12-13 03:48:25

问题


I know that Entity Framework has some LINQ support problems (at least in comparison to its predecessor LINQ to SQL)...and usually I'm able to find a creative way of restructuring my LINQ query so that it's supported by EF and doesn't throw a

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

But this time I'm having trouble. As usual, the problem is related to complex joins. This time it's required for modeling some legacy data I'm working with.

I have a query for Offices (a simple 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;
    }
}

Then I have something else that has an Office property on it.

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,
            };
    }
}

Please note, telling me to make it an enumerable defeats the purpose...so please don't advise that.

And so....doing CalendarEntries.ToArray() throws "Unable to create a constant value of type Office"...

Specifically the problem is the let mainOffice = Offices.First(). If I remove that logic, the query works fine. Any idea how to make this work with Entity Framework?

Thanks.


回答1:


Yep ok, looks like the double queryable is tripping it up. Only option is to either left join to Offices or do the following:

       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,
                          };

I'm assuming you didn't want to do that due to complaints about making it IEnumerable so you will need to join to the Offices queryable some how to tell EF how to string the queries together. Let x = y or value = value is looking for a constant which i guess makes sense.




回答2:


First executes query when expression tree is constructed so it tries passing Office as parameter to your query which cannot be done.

One way to replace First is calling this.Offices.Take(1).



来源:https://stackoverflow.com/questions/6165425/entity-framework-complex-linq-support

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!