C#实体框架数据库首先 - 仅使用一些字段

时间:2016-08-10 15:33:45

标签: c# asp.net asp.net-mvc entity-framework ef-database-first

我正在使用EF数据库创建一个站点 - 首先使用ASP.NET MVC(我遵循本教程的所有内容:https://www.asp.net/mvc/overview/getting-started/database-first-development/creating-the-web-application),一切正常。

问题是在索引视图(记录列表)中我想从实体中删除其中一个字段。我不仅希望它隐藏在视图中,而是一起删除(问题是它拥有非常大的数据块,这使得列表的加载速度非常慢)。

在“编辑”视图中,我想显示并使用所有字段。

如果我从实体中删除一个字段,我会收到此错误:

  

实体类型XXX不是当前上下文模型的一部分。

on

 return View(db.XXX.ToList());

我该怎么办?

1 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题。手头的问题是.ToList()。 如果您只是执行db.XXX,那么您将获得一个Enumerable,在枚举之前,它只是一组从数据库中获取数据的指令。一旦你调用.ToList(),它实际上就会从数据库中获取数据,这是花费这么长时间的步骤。

在我看来,最好的办法是定义一个ViewModel,它包含除了具有大量数据的字段之外的所有字段。

public class ViewModel
{ 
     public ViewModel(){}
     public int Id {get;set;}
     public string OtherData {get;set;}
}

移动 db.XXX之外的View函数如下:

var initialDBObject = db.XXX;

从那里你可以获取你的Enumerable(它仍然是一组从数据库访问数据的指令)并将它选择到你的ViewModel对象中,如下所示:

var viewModelObject = initialDBObject.Select(x=> new ViewModel
    {
        Id = x.Id;
        OtherData = x.OtherData;
        //do not add the large column of data to the ViewModel
    });

这里发生了什么(在调用ToList()之前)你正在修改linq在幕后生成的查询以从表XXX中获取数据(如果你在这一行上放置一个断点并将鼠标悬停在initialDBObject上,你将会看到生成的SQL)。一旦调用ToList(),查询将获取数据并将其插入ViewModel对象(而不是.edmx文件中定义的XXX对象),而不是仅仅从表XXX中获取数据。

你也可以

.Select(x=> new 
{
    Id, 
    OtherData
});

并创建一个匿名对象,但让一个匿名对象在View中工作有点复杂。

然后,您需要更新“索引视图”页面以使用ViewModel而不是原始数据库对象,您可以将其传递给:

View(viewModelObject.ToList()); 

将ViewModel命名为ViewModel之外的东西。像[DB Table Name] ViewModel或类似的东西。

如果数据库中有很多行,那么加载所有数据仍然需要很长时间,在这种情况下,您需要查看分页。

ToList()本身没有问题,原来的问题是由对ToList()的调用引起的,因为它是代码中的那个点,程序进入数据库并使用linq生成的查询以获取数据。如果你试图ToList()整个表的数据,或者像你的情况那样,有一个包含大量数据的列,可能需要一些时间,或者你可能会耗尽内存。

关于你必须包含在.Select()中的15列,是的,这很烦人。不幸的是,你不能在linq语句中使用构造函数,所以强制填充每一列。

定义ViewModel的另一种替代方法是打开.edmx设计图面,右键单击背景并添加New-> Entity,这可能更容易一些。您可以使用表XXX作为基础,给它一个不同的名称,如XXXViewModel或其他任何名称,然后删除包含大量数据的列。然后你只需要做db.XXXViewModel.ToList()。