一、常见问题
有时候遇到视图添加不进模型编辑器里,不理解EF机制的小白很是无解,而且EF编辑器愣是报一些没有价值的错误信息:
模型已生成,但出现警告或错误。
有关详细信息,请参阅错误列表。运行应用程序前需要修复这些问题。
其实这些问题归根结底可以用Microsoft官网上的一句话来解答:
但是对于视图一些没有表主键的情况,EF生成器是怎么生成模型Key的?在官网里没有介绍,只能自己总结。
二、EF生成器是怎么为视图分配Key的
以下是我总结的三点(可以右键edmx生成器,用xml格式打开模型进行查看):
1. 没有主键的单表查询,EF编辑器会默认第一个字段为主键
CREATE VIEW AA AS
SELECT B.Name,B.Mobile FROM [User] B
对应生成的模型:
<!--生成过程中发现错误:
警告 6002: 表/视图“TestDB.dbo.AA”未定义主键。已推断出该键,并将定义创建为只读的表/视图。
-->
<EntityType Name="AA">
<Key>
<PropertyRef Name="Name" />
</Key>
<Property Name="Name" Type="varchar" Nullable="false" MaxLength="50" />
<Property Name="Mobile" Type="varchar" MaxLength="20" />
</EntityType>
2. 多表查询,字段中包含主表主键,则使用主表主键,没有则使用主表中的所有字段作为主键
所以此情况的视图中必须带有主表的字段,不然就会报错且不会将此视图加入EF编辑器
CREATE VIEW [dbo].[V_UserInfo] AS
SELECT
u.Name,
u.Mobile,
f.ExTime,
f.No,
t.A
FROM [User] u
LEFT OUTER JOIN IdCardInfo f ON f.UserId=u.UserId
LEFT OUTER JOIN TableB t ON t.Id=f.Id
对应生成的模型:
<!--生成过程中发现错误:
警告 6002: 表/视图“TestDB.dbo.V_UserInfo”未定义主键。已推断出该键,并将定义创建为只读的表/视图。
-->
<EntityType Name="V_UserInfo">
<Key>
<PropertyRef Name="Name" />
<PropertyRef Name="Mobile" />
</Key>
<Property Type="String" Name="Name" MaxLength="50" />
<Property Type="Int32" Name="Mobile" Nullable="false" />
<Property Type="Int32" Name="ExTime" Nullable="false" />
<Property Type="Int32" Name="No" Nullable="false" />
<Property Type="Int32" Name="A" Nullable="false" />
</EntityType>
3. 多表查询+GROUP BY 的视图,默认使用GROUP BY 的字段作为键值
CREATE VIEW [dbo].[V_CountUser] AS
SELECT
f.ExTime,
f.Type,
COUNT(u.UserId) AS UserCount
FROM [User] u
LEFT OUTER JOIN IdCardInfo f ON f.UserId=u.UserId
LEFT OUTER JOIN TableB t ON t.Id=f.Id
GROUP BY F.ExTime,F.Type
对应生成的模型:
<!--生成过程中发现错误:
警告 6002: 表/视图“TestDB.dbo.V_UserInfo”未定义主键。已推断出该键,并将定义创建为只读的表/视图。
<EntityType Name="V_CountUser">
<Key>
<PropertyRef Name="ExTime" />
<PropertyRef Name="Type" />
</Key>
<Property Type="DateTime" Name="ExTime" Precision="3" />
<Property Type="Int32" Name="Type" Nullable="false" />
<Property Type="Int32" Name="UserCount" Nullable="false" />
</EntityType>