实体框架和SQL Server视图
由于以下几个我没有自由讨论的理由,我们正在定义一个对我们的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来生成模型。 有没有办法不让实体框架包含这个视图的任何字段作为主键?
我们遇到了同样的问题,这就是解决方案:
要强制实体框架使用列作为主键,请使用ISNULL。
要强制实体框架不要使用列作为主键,请使用NULLIF。
一个简单的方法来应用这个是在另一个select中包装你的视图的select语句。
例:
SELECT
ISNULL(MyPrimaryID,-999) MyPrimaryID,
NULLIF(AnotherProperty,'') AnotherProperty
FROM ( ... ) AS temp
我能够用设计师解决这个问题。
我不必将视图更改为使用ISNULL,NULLIF或COALESCE解决方法。 如果您从数据库更新模型,则警告将重新出现,但如果您关闭并重新打开VS,将会消失。 您在设计器中所做的更改将被保留,不会受到刷新的影响。
同意@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)在计划中包含正确的索引。
如果
链接地址: http://www.djcxy.com/p/29149.html