实体框架和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

我能够用设计师解决这个问题。

  • 打开模型浏览器。
  • 在图中找到视图。
  • 右键点击主键,并确保选中“实体键”。
  • 多选所有非主键。 使用Ctrl或Shift键。
  • 在“属性”窗口中(如果需要查看,请按F4键),将“实体键”下拉列表更改为False。
  • 保存更改。
  • 关闭Visual Studio并重新打开它。 我正在使用Visual Studio 2013与EF 6,我不得不这样做,让警告消失。
  • 我不必将视图更改为使用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

    上一篇: Entity Framework and SQL Server View

    下一篇: asp.net mvc modular application howto/recommendations