Ser*_*ero 131 entity-framework sql-server-2005 primary-key .net-3.5 sql-view
由于几个我无权谈论的原因,我们在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
Run Code Online (Sandbox Code Playgroud)
我们的想法是,实体框架将基于此查询创建一个实体,但它会生成一个包含以下内容的错误:
警告6002:表/视图'Keystone_Local.dbo.MeterProvingStatisticsPoint'没有定义主键.已推断密钥,并将定义创建为只读表/视图.
并且它决定CompletedDateTime字段将是此实体主键.
我们正在使用EdmGen生成模型.有没有办法不让实体框架包含此视图的任何字段作为主键?
Til*_*ito 238
我们遇到了同样的问题,这就是解决方案:
要强制实体框架使用列作为主键,请使用ISNULL.
要强制实体框架不使用列作为主键,请使用NULLIF.
一种简单的方法是将视图的select语句包装在另一个select中.
例:
SELECT
ISNULL(MyPrimaryID,-999) MyPrimaryID,
NULLIF(AnotherProperty,'') AnotherProperty
FROM ( ... ) AS temp
Run Code Online (Sandbox Code Playgroud)
Cas*_*mer 66
我能够使用设计师解决这个问题.
我没有必要更改我的视图以使用ISNULL,NULLIF或COALESCE解决方法.如果您从数据库更新模型,警告将重新出现,但如果您关闭并重新打开VS,它将会消失.您在设计器中所做的更改将被保留,并且不会受到刷新的影响.
Val*_*tin 45
同意@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);
Run Code Online (Sandbox Code Playgroud)
你的观点是这样的
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
Run Code Online (Sandbox Code Playgroud)
Sql优化器不会使用索引ix_customer,它会对主索引执行表扫描,但是如果不是:
Group by CustomerId
Run Code Online (Sandbox Code Playgroud)
你用
Group by IsNull(CustomerId, -1)
Run Code Online (Sandbox Code Playgroud)
它将使MS SQL(至少2008年)包括正确的索引到计划中.
如果
这种方法对我很有用.我使用ISNULL()作为主键字段,如果字段不应该是主键,则使用COALESCE(),但也应该具有不可为空的值.此示例生成具有不可为空的主键的ID字段.其他字段不是键,并且(None)作为Nullable属性.
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
Run Code Online (Sandbox Code Playgroud)
如果你真的没有主键,你可以使用ROW_NUMBER来生成一个被代码忽略的伪键.例如:
SELECT
ROW_NUMBER() OVER(ORDER BY A,B) AS Id,
A, B
FROM SOMETABLE
Run Code Online (Sandbox Code Playgroud)
当前的实体框架 EDM 生成器将从视图中的所有不可为空字段创建组合键。为了获得对此的控制,当您不希望它们成为主键的一部分时,您需要修改视图和基础表列,将这些列设置为可为空。相反的情况也是如此,正如我遇到的那样,EDM 生成的键导致了数据重复问题,因此我必须将可为空的列定义为不可为空,以强制 EDM 中的复合键包含该列。
归档时间: |
|
查看次数: |
101436 次 |
最近记录: |