4

我是 ASPNET 和 MVC 4 的新手,所以我想这可能是一个简单的问题。但是,我一直无法正确地用谷歌搜索答案。我只想显示一些销售信息 - 我需要显示它。我不需要从基础表中插入、更新或删除。

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

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

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

这显然不是处理这个问题的正确方法。有没有办法从视图中创建强类型模型?我宁愿让 ASP.NET 中的 Controller 和 View 对象从模型中的 SQL 视图正确地自动生成,而不是需要这个空白表来“欺骗”系统。

提前谢谢了。

4

3 回答 3

4

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

通常,在使用实体框架时避免使用视图。创建一个 linq 查询来执行您的视图所做的操作并使用它。

于 2013-03-11T21:19:14.847 回答
2

Entity Framework 确实不喜欢 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; }

当我搭建这个脚手架并显示索引视图时,我收到一个引用主键的错误。显然,实体框架假定所有非空字段都有助于主键。

删除额外的非空值就可以了。我使用以下命令强制视图中的列可以为空:

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)

一旦我更改了视图,索引视图就可以正常工作。

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

当然,这里的假设是您有权修改视图(或者可以创建替代视图)。我只能确认这适用于 MVC 5 和 Entity Framework 6。

于 2016-09-16T17:01:41.910 回答
1

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

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

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

于 2013-03-11T21:26:00.913 回答