实体框架-从视图创建模型

本文关键字:创建 模型 视图 框架 实体 | 更新日期: 2023-09-27 18:03:37

我是asp.net和MVC 4的新手,所以我想这可能是一个简单的问题。然而,我一直无法正确地谷歌答案。我只是想显示一些销售信息-我只有需要显示它。我不需要从底层表中插入、更新或删除。

需要从3个SQL Server表中提取数据:CurrentSales, SalesPlans和AverageSales。我为此创建了一个VIEW,并在其上放置了唯一的聚集索引;它包含一些外部连接,但具有处理任何不可能的NULL值的逻辑。

我去模型,添加一个新的ADO。. NET实体数据模型,并将我的视图添加到模型中。它回来说表/视图'vw_FullView'没有定义主键。键已经被推断出来,定义被创建为只读表/视图。"当我从这个模型和实体中创建一个Controller类时,当我加载网站时,视图没有显示任何数据。

然而,如果我创建一个完全空白的表——使用适当的主键——作为模型表,然后使用存储过程(作为函数导入)来检索我需要的数据,一切都很好。

这显然不是正确的处理方法。有没有一种方法可以在视图之外创建强类型模型?我更喜欢在ASP中有控制器和视图对象。. NET正确地从模型中的SQL视图自动生成,而不是需要这个空白表来"愚弄"系统。

提前感谢。

实体框架-从视图创建模型

实体框架不太喜欢视图。它无法确定视图的主键是什么,因此它假设任何非空字段都是复合主键的一部分。

一般来说,在使用实体框架时避免使用视图。创建一个linq查询来代替你的视图,

这是真的,实体框架不喜欢SQL Server视图,因为主键在视图中不明显。不幸的是,在模型中指定[Key]似乎是不够的。然而,它可以做到,并且在98%的情况下非常有用,其中有一个视图,合并表,你只是想在网格中显示它的数据。关键(请原谅双关语)是正确定义视图。

我原来的视图包含以下几列:

DepartmentCode(varchar(8),not null)
DepartmentName(varchar(60), not null)
DivisionCode(varchar(8), null)
DivisionName(varchar(8), null)
StatusCode(char(1), not null)
Virtual(varchar(1), not null)

在我的模型中我指定了

[Key]
[Column("DepartmentCode")]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[StringLength(8)]
[Display(Name = "Department Code")]
public string DepartmentCode { get; set; }

当我搭建这个框架并显示Index视图时,我得到了一个引用主键的错误。显然,实体框架假定所有非空字段都构成主键。

去掉多余的非空值就成功了。我使用以下命令强制视图中的列为可空的:

CREATE view [dbo].[Departments] as
select DepartmentCode
,nullif(DepartmentName,'') as DepartmentName
,nullif(DivisionCode,'') as DivisionCode
,nullif(DivisionName,'') as DivisionName
,nullif(StatusCode,'') as StatusCode
,nullif(Virtual,'') as Virtual
from ....

现在视图列看起来像这样

DepartmentCode(varchar(8),not null)
DepartmentName(varchar(60), null)
DivisionCode(varchar(8), null)
DivisionName(varchar(8), null)
StatusCode(char(1), null)
Virtual(varchar(1), null)

一旦我改变了视图,Index视图就正常工作了。

我还确认,包含复合(多列)键的视图也可以工作,只要这些列不为空,并且在您的模型中,您在每列上指定[key],并在这些键列上的[column]注释中添加Order=1和Order=2。

当然,这里的假设是您有修改视图的权限(或者可以创建一个备用视图)。我只能确认这适用于MVC 5和实体框架6。

视图只是一个实体或多个实体的投影。默认情况下,实体框架将只允许只读访问,因为视图中没有真正的实体,这意味着ET无法跟踪更改。

simmdan实际上在MSDN论坛上很好地解释了如何解决这个问题

基本上,正如Mystere Man已经指出的那样,如果你使用实体框架,最简单的方法是使用linq连接和过滤的真实实体来克隆你的视图。