C# 实体框架使用扩展方法引发异常

C# 实体框架使用扩展方法引发异常,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我的控制器中有以下代码: public List<DockDoorViewModel> GetDoorViewModel() { List<DockDoorViewModel> doors = new List<DockDoorViewModel>(); for (int i = 1; i < 11; i++) { // This is where the Stack Trace is pointing to.

我的控制器中有以下代码:

public List<DockDoorViewModel> GetDoorViewModel()
{
    List<DockDoorViewModel> doors = new List<DockDoorViewModel>();

    for (int i = 1; i < 11; i++)
    {
        // This is where the Stack Trace is pointing to.
        DockDoorViewModel door = db.vwDockDoorDatas
                                   .Where(x => x.DockNo == i)
                                   .Select(x => x.ToDockDoorViewModel())
                                   .FirstOrDefault();

        if (door == null)
        {
            door = new DockDoorViewModel(i);
        }
        else
        {
            door.Items = db.vwDockDoorDatas
                           .Where(x => x.DockNo == i)
                           .Select(x => x.ToDockDoorItem())
                           .ToList();
        }

        doors.Add(door);
    }

    return doors;
}

我以前做过这种事情,所以我不知道我做错了什么?这是我第一次使用MVC5和EF6应用程序。

在使用to方法之前,必须从SQL Server加载数据。您可以使用以下命令(例如)执行此操作:

door.Items = db.vwDockDoorDatas
                           .Where(x => x.DockNo == i)
                           .ToList() //Possibly use AsEnumerable() here instead as James says
                           .Select(x => x.ToDockDoorItem())
                           .ToList();

在使用to方法之前,必须从SQL Server加载数据。您可以使用以下命令(例如)执行此操作:

door.Items = db.vwDockDoorDatas
                           .Where(x => x.DockNo == i)
                           .ToList() //Possibly use AsEnumerable() here instead as James says
                           .Select(x => x.ToDockDoorItem())
                           .ToList();

错误消息告诉您需要知道的一切-EF无法将扩展方法转换为SQL,因此引发异常。您需要将查询从LINQ转换为实体到LINQ转换为对象,只需调用
AsEnumerable()
即可

DockDoorViewModel door = db.vwDockDoorDatas.Where(x => x.DockNo == i)
                                           .AsEnumerable()
                                           .Select(x => x.ToDockDoorViewModel())
                                           .FirstOrDefault();
实际上,这会创建一个混合查询,其中
AsEnumerable
之前的所有内容都被转换并作为SQL执行,其余部分在客户端和内存中执行


根据您的性能问题,再次查看您的查询时,您不必要地浏览了大量记录,您只关注第一条记录,因此为什么不直接浏览那条记录呢

vwDockDoorData entity = db.vwDockDoorDatas.Where(x => x.DockNo == i)
                                          .FirstOrDefault();
DockDoorViewModel door = entity != null ? entity.ToDockDoorViewModel() : null;
对此的进一步改进是,在迭代记录之前只需过滤记录(给您一个开始/结束范围),例如


var doorDatas=db.vwDockDoorDatas.Where(x=>x.DockNo>=1&&x.DockNo错误消息告诉您真正需要知道的一切-EF无法将扩展方法转换为SQL,因此引发异常。您需要将查询从LINQ转换为实体到LINQ转换为对象,只需调用
AsEnumerable()
即可

DockDoorViewModel door = db.vwDockDoorDatas.Where(x => x.DockNo == i)
                                           .AsEnumerable()
                                           .Select(x => x.ToDockDoorViewModel())
                                           .FirstOrDefault();
实际上,这会创建一个混合查询,其中
AsEnumerable
之前的所有内容都被转换并作为SQL执行,其余部分在客户端和内存中执行


根据您的性能问题,再次查看您的查询时,您不必要地浏览了大量记录,您只关注第一条记录,因此为什么不直接浏览那条记录呢

vwDockDoorData entity = db.vwDockDoorDatas.Where(x => x.DockNo == i)
                                          .FirstOrDefault();
DockDoorViewModel door = entity != null ? entity.ToDockDoorViewModel() : null;
对此的进一步改进是,在迭代记录之前只需过滤记录(给您一个开始/结束范围),例如


var doorDatas=db.vwDockDoorDatas.Where(x=>x.DockNo>=1&&x.DockNo在这种情况下,选择
aseneumerable
通常更好,因为您仍然保留延迟执行。在这种情况下,选择
aseneumerable
通常更好,因为您仍然保留延迟执行。这很有效,谢谢。现在我只需要你知道为什么查询速度如此之慢。@RefractedPaladin很清楚,你的大部分查询现在都在内存中运行,因此根据结果集,结果可能会非常慢。你从SQL视图中提取了多少个结果?130个。大约15列。非“宽”虽然视图本身在ManagementStudio中运行需要4秒。但有一个问题,视图是否每次循环都必须“重新运行”?因此我添加了以下内容:
var data=db.vwDockDoorDatas.ToList()
就在我的
for
循环和性能飙升之前。我看到了你关于
可枚举的注释,但这并没有改变任何事情。也许我不应该为此使用SQL视图。存储过程可能…@RefractedPaladin“每次我循环它时,视图都必须“重新运行”吗?”-这完全取决于循环的性质,你能举个例子吗?调用
ToList
将返回你的整个结果集,所以我并不感到惊讶…这很有效,谢谢。现在我只需要弄清楚为什么它速度如此之慢。@RefractedPaladin很清楚,你的大部分查询现在都在内存中运行,这取决于结果集结果可能非常慢。您从SQL视图中提取了多少个结果?130个。大约15列。虽然视图本身在Management Studio中运行需要4秒,但不是“宽”。问题是,视图是否每次循环都必须“重新运行”?因此我添加了以下内容:
var data=db.vwdockdordatas.ToList()
就在我的
for
循环和性能飙升之前。我看到了你关于
可枚举的注释,但这并没有改变任何事情。也许我不应该为此使用SQL视图。存储过程可能…@RefractedPaladin“每次我循环它时,视图都必须“重新运行”吗?”-这完全取决于循环的性质,你能举个例子吗?调用
ToList
将返回你的整个结果集,所以我并不感到惊讶。。。