由于一些原因,我没有自由谈,我们为我们的SQL Server上定义2005数据库,像这样一个观点:
CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
CAST(0 AS BIGINT) AS 'RowNumber',
CAST(0 AS BIGINT) AS 'ProverTicketId',
CAST(0 AS INT) AS 'ReportNumber',
GETDATE() AS 'CompletedDateTime',
CAST(1.1 AS float) AS 'MeterFactor',
CAST(1.1 AS float) AS 'Density',
CAST(1.1 AS float) AS 'FlowRate',
CAST(1.1 AS float) AS 'Average',
CAST(1.1 AS float) AS 'StandardDeviation',
CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1
这个想法是,实体框架将在此基础上查询,其中它创建一个实体,但它指出以下错误产生的:
警告6002:表/图“Keystone_Local.dbo.MeterProvingStatisticsPoint”不具有定义的主键。 关键已经推断和定义,为只读表/视图中创建。
并判断出CompletedDateTime领域将这个实体的主键。
我们使用EdmGen生成模型。 有没有办法不具有实体框架包括这一观点作为主键的任何领域?
Answer 1:
我们有同样的问题,这是解决方案:
要强制实体框架使用的列作为主键,使用ISNULL。
要强制实体框架不使用的列作为主键,使用NULLIF。
应用此一个简单的方法来包装你的视图的select语句中的另一个选择。
例:
SELECT
ISNULL(MyPrimaryID,-999) MyPrimaryID,
NULLIF(AnotherProperty,'') AnotherProperty
FROM ( ... ) AS temp
Answer 2:
我能够使用设计器来解决这个问题。
- 打开模型浏览器。
- 查找图中的视图。
- 右键点击主键,并确保“实体键”被选中。
- 多选择所有非主键。 使用Ctrl或Shift键。
- 在属性窗口(如果需要的话,看看它按F4键),改变“实体键”下拉为False。
- 保存更改。
- 关闭Visual Studio和重新打开它。 我使用Visual Studio 2013与EF 6,我不得不这样做是为了得到警告消失。
我没有改变我的看法使用ISNULL,NULLIF,COALESCE或解决方法。 如果您更新了数据库模型,警告将重新出现,但如果关闭并重新打开VS.将消失 您在设计所做的更改将被保留,并不会受刷新。
Answer 3:
与@Tillito同意,但在大多数情况下,犯规SQL优化器,它不会使用正确的索引。
这可能为某人是显而易见的,但我烧个小时解决在使用Tillito解决性能问题。 比方说你有表:
Create table OrderDetail
(
Id int primary key,
CustomerId int references Customer(Id),
Amount decimal default(0)
);
Create index ix_customer on OrderDetail(CustomerId);
你的看法是这样的
Create view CustomerView
As
Select
IsNull(CustomerId, -1) as CustomerId, -- forcing EF to use it as key
Sum(Amount) as Amount
From OrderDetail
Group by CustomerId
SQL优化器不会使用索引ix_customer,它会在主索引进行表扫描,但如果不是的:
Group by CustomerId
你用
Group by IsNull(CustomerId, -1)
它将使MS SQL(至少2008年),包括正确索引的计划。
如果
Answer 4:
这种方法很适合我。 我使用ISNULL()主键字段,COALESCE()如果该字段不应该是主键,但也应该有一个非空值。 此示例产生ID字段具有非空的主键。 其他字段都没有钥匙,有(无)作为其可空属性。
SELECT
ISNULL(P.ID, - 1) AS ID,
COALESCE (P.PurchaseAgent, U.[User Nickname]) AS PurchaseAgent,
COALESCE (P.PurchaseAuthority, 0) AS PurchaseAuthority,
COALESCE (P.AgencyCode, '') AS AgencyCode,
COALESCE (P.UserID, U.ID) AS UserID,
COALESCE (P.AssignPOs, 'false') AS AssignPOs,
COALESCE (P.AuthString, '') AS AuthString,
COALESCE (P.AssignVendors, 'false') AS AssignVendors
FROM Users AS U
INNER JOIN Users AS AU ON U.Login = AU.UserName
LEFT OUTER JOIN PurchaseAgents AS P ON U.ID = P.UserID
如果你真的没有一个主键,您可以通过使用ROW_NUMBER生成是由你的代码忽略了伪键恶搞之一。 例如:
SELECT
ROW_NUMBER() OVER(ORDER BY A,B) AS Id,
A, B
FROM SOMETABLE
Answer 5:
当前实体框架电火花发生器将创建一个从您的视图中的所有非可空领域的复合键。 为了获得在这个控制,则需要修改视图和基础表列设置列可空当你不希望他们成为主键的一部分。 相反的情况也是如此,因为我遇到的EDM生成的密钥是导致数据的重复数据删除的问题,所以我不得不定义一个空的列为非null迫使在EDM复合键包含的该列。
Answer 6:
看起来这是一个已知的问题EdmGen: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/
Answer 7:
为了得到一个观点,我不得不只显示一个主键列我创建的提到了第一次和使用NULLIF使类型可为空的第二个观点。 这为我工作,使EF认为只是在视图中的单个主键。
不知道这是否会帮助你,尽管因为我不相信EF会接受没有主键的实体。
Answer 8:
我还建议,如果你不想用什么应该是主键纳入到ROW_NUMBER您的选择,并设置为主键,将所有其他列/承包商,客人如在模型非主一塌糊涂。
Answer 9:
由于上述提到的问题,我更喜欢表值函数。
如果你有这样的:
CREATE VIEW [dbo].[MyView] AS SELECT A, B FROM dbo.Something
创建这个:
CREATE FUNCTION MyFunction() RETURNS TABLE AS RETURN (SELECT * FROM [dbo].[MyView])
然后,只需导入函数,而不是视图。
文章来源: Entity Framework and SQL Server View