【问题标题】:Can't Add A View to EF Data Model无法将视图添加到 EF 数据模型
【发布时间】:2011-08-27 03:14:03
【问题描述】:

我有一个视图,我正在尝试将其添加到我的 ADO.NET 实体数据模型中。每次我尝试从数据库更新并检查视图时,它都会刷新其他所有内容,但不会添加视图。
我没有收到错误消息或输出,所以我不知道视图有什么问题。其他观点都没有问题。我错过了什么,有没有办法打开错误消息? Visual Studio 2008 sp1

更新:我找到了这个链接,但这些解决方案没有解决问题。 MSDN Forum

更新:我无法添加的视图将从另一个视图中查询。

更新:帮助

WITH cte AS (SELECT     dbo.TBL_Gharardad.PK_Shenase, dbo.TBL_Gharardad.FK_NoeKhedmat AS NoeKhedmatId, 
                                                    dbo.TBL_NoeKhedmat.NoeKhedmat AS [نوع خدمت], dbo.TBL_Gharardad.OnvaneKhedmat AS [عنوان خدمت], 
                                                    dbo.TBL_Gharardad.MahaleEraeieKhedmat AS [محل ارائه خدمت], 
                                                    dbo.TBL_Gharardad.FK_NahveieTaieeneBarande AS NahveieTaeeneBararndeId, 
                                                    dbo.TBL_NahveieTaieeneBarande.NahveieTaieeneBarande AS [نحوه تعيين برنده], 
                                                    dbo.TBL_Gharardad.TarikheShorooeGharardad_Jalali AS [تاريخ شروع قرارداد], 
                                                    dbo.TBL_Gharardad.TarikhePayaneGharardad_Jalali AS [تاريخ پايان قرارداد], dbo.TBL_Gharardad.FK_VahedeArz AS VahedeArzId, 
                                                    dbo.TBL_VahedeArz.VahedeArz AS [واحد ارز], dbo.TBL_Gharardad.MablagheDariaftiKol AS [مبلغ دريافتي کل], 
                                                    dbo.TBL_Gharardad.MablaghePardakhtieKol AS [مبلغ پرداختي کل], dbo.TBL_Gharardad.SahmeKarfarma AS [درصد مشارکت کارفرما], 
                                                    100 - dbo.TBL_Gharardad.SahmeKarfarma AS [درصد مشارکت پيمانکار], dbo.TBL_Gharardad.TedadNirooyeMard AS [تعداد نيروي مرد], 
                                                    dbo.TBL_Gharardad.TedadNirooyeZan AS [تعداد نيروي زن], 
                                                    dbo.TBL_Gharardad.TedadNirooyeMard + dbo.TBL_Gharardad.TedadNirooyeZan AS [تعداد کل نيروها], 
                                                    dbo.TBL_Gharardad.FK_TarafeGharardad AS TarafeGharardadId, 
                                                    CASE TBL_TarafeGharardad.Hoghooghi WHEN 0 THEN ISNULL(TBL_TarafeGharardad.Naam, ' ') 
                                                    + ' ' + ISNULL(TBL_TarafeGharardad.NaameKhanevadegi, ' ') ELSE TBL_TarafeGharardad.NameSherkat END AS [طرف قرارداد], 
                                                    dbo.TBL_Gharardad.FK_VahedeVagozarKonande AS VahedeVagozarKonandeId, 
                                                    dbo.TBL_VahedeVagozarKonande.VahedeVagozarKonande AS [واحد واگذار کننده], dbo.TBL_Gharardad.ShomareGharardad AS [شماره قرارداد], 
                                                    dbo.TBL_Gharardad.TarikheGharardad_Jalali AS [تاريخ قرارداد], 
                                                    CASE VaziateGharardad WHEN 0 THEN N'لغو شده' WHEN 1 THEN N'ثبت اوليه' WHEN 2 THEN N'فسخ' WHEN 3 THEN N'ثبت نهايي ' WHEN 4 THEN
                                                     N' جاري ' WHEN 5 THEN N'تمام شده ' WHEN 6 THEN N' متمم ' END AS [وضعيت قرارداد], dbo.TBL_NoeMoamele.NoeMoamele AS [نوع معامله]
                             FROM          dbo.TBL_Gharardad INNER JOIN
                                                    dbo.TBL_NoeKhedmat ON dbo.TBL_Gharardad.FK_NoeKhedmat = dbo.TBL_NoeKhedmat.PK_Id INNER JOIN
                                                    dbo.TBL_NahveieTaieeneBarande ON 
                                                    dbo.TBL_Gharardad.FK_NahveieTaieeneBarande = dbo.TBL_NahveieTaieeneBarande.PK_Id INNER JOIN
                                                    dbo.TBL_VahedeArz ON dbo.TBL_Gharardad.FK_VahedeArz = dbo.TBL_VahedeArz.PK_Id INNER JOIN
                                                    dbo.TBL_TarafeGharardad ON dbo.TBL_Gharardad.FK_TarafeGharardad = dbo.TBL_TarafeGharardad.PK_Id INNER JOIN
                                                    dbo.TBL_VahedeVagozarKonande ON 
                                                    dbo.TBL_Gharardad.FK_VahedeVagozarKonande = dbo.TBL_VahedeVagozarKonande.PK_Id INNER JOIN
                                                    dbo.TBL_NoeMoamele ON dbo.TBL_Gharardad.FK_NoeMoamele = dbo.TBL_NoeMoamele.PK_Id)
    SELECT     v_Gharardad.شناسه, v_Gharardad.NoeKhedmatId, v_Gharardad.[نوع خدمت], v_Gharardad.[عنوان خدمت], v_Gharardad.[محل ارائه خدمت], 
                            v_Gharardad.NahveieTaeeneBararndeId, v_Gharardad.[نحوه تعيين برنده], v_Gharardad.[تاريخ شروع قرارداد], v_Gharardad.[تاريخ پايان قرارداد], 
                            v_Gharardad.VahedeArzId, v_Gharardad.[واحد ارز], v_Gharardad.[مبلغ دريافتي کل], v_Gharardad.[مبلغ پرداختي کل], v_Gharardad.[درصد مشارکت کارفرما], 
                            v_Gharardad.[درصد مشارکت پيمانکار], v_Gharardad.[تعداد نيروي مرد], v_Gharardad.[تعداد نيروي زن], v_Gharardad.[تعداد کل نيروها], 
                            v_Gharardad.TarafeGharardadId, v_Gharardad.[طرف قرارداد], v_Gharardad.VahedeVagozarKonandeId, v_Gharardad.[واحد واگذار کننده], 
                            v_Gharardad.[شماره قرارداد], v_Gharardad.[تاريخ قرارداد], v_Gharardad.[وضعيت قرارداد], v_Gharardad.[نوع معامله]
     FROM         dbo.TBL_Gharardad AS TBL_Gharardad_3 INNER JOIN
                            dbo.v_GharardadRecords AS v_Gharardad ON v_Gharardad.شناسه = TBL_Gharardad_3.PK_Shenase
     WHERE     (TBL_Gharardad_3.FK_GharardadeAsli IS NULL) AND (TBL_Gharardad_3.PK_Shenase NOT IN
                                (SELECT     FK_GharardadeAsli
                                   FROM         dbo.TBL_Gharardad AS TBL_Gharardad_2
                                   WHERE     (FK_GharardadeAsli IS NOT NULL)))
UNION
SELECT     sub.FK_GharardadeAsli AS شناسه, cte_2.NoeKhedmatId, cte_2.[نوع خدمت], cte_2.[عنوان خدمت], cte_2.[محل ارائه خدمت], cte_2.NahveieTaeeneBararndeId, 
                      cte_2.[نحوه تعيين برنده], cte_2.[تاريخ شروع قرارداد], cte_2.[تاريخ پايان قرارداد], cte_2.VahedeArzId, cte_2.[واحد ارز], cte_2.[مبلغ دريافتي کل], cte_2.[مبلغ پرداختي کل], 
                      cte_2.[درصد مشارکت کارفرما], cte_2.[درصد مشارکت پيمانکار], cte_2.[تعداد نيروي مرد], cte_2.[تعداد نيروي زن], cte_2.[تعداد کل نيروها], cte_2.TarafeGharardadId, 
                      cte_2.[طرف قرارداد], cte_2.VahedeVagozarKonandeId, cte_2.[واحد واگذار کننده], cte_2.[شماره قرارداد], cte_2.[تاريخ قرارداد], cte_2.[وضعيت قرارداد], 
                      cte_2.[نوع معامله]
FROM         dbo.v_GharardadRecords AS cte_2 INNER JOIN
                          (SELECT     FK_GharardadeAsli, MAX(PK_Shenase) AS PK_Shenase, MAX(TarikheSabt) AS TarikheSabt
                             FROM         dbo.TBL_Gharardad AS TBL_Gharardad_1
                             WHERE     (FK_GharardadeAsli IS NOT NULL)
                             GROUP BY FK_GharardadeAsli) AS sub ON sub.PK_Shenase = cte_2.شناسه

【问题讨论】:

  • 如果没有添加任何项目到模型中,应该有一些信息消息。您的视图中是否有任何不可为空的列?如果不是 EF 将无法添加它。
  • 无法添加的视图会从另一个视图查询。
  • 但 EF 仍然必须推断主键。如果 EF 不推断主键,它将跳过数据库对象。以 XML 格式打开 EDMX 并检查视图是否位于 XML (SSDL) 的第一部分。
  • 另一件事:我认为我使用过 CTE
  • CTE 应该不是问题,我已经使用它并且它有效。你能显示视图的 SQL 吗?

标签: entity-framework visual-studio-2008-sp1


【解决方案1】:

如果您的视图不包含主键列,则它不会添加到 edmx 文件中。

【讨论】:

  • 另外键必须是不可为空的。编译器 edmx 一直在更新失败,直到我删除并重新导入视图。
  • 如果视图没有键,则伪造一个:SELECT ISNULL(ROW_NUMBER() OVER (ORDER BY MyColumn), 0) AS UniqueId ...
  • 您能解释一下为什么这对于 EF 生成模型是必要的吗?我很想知道它为什么会这样工作。
【解决方案2】:

当我尝试添加一个不从另一个表中选择主键的视图时,我遇到了同样的行为。 (就像 Ladislav Mrnka 评论的那样)

我解决此问题的策略是将视图简化为尽可能简单(1 列)并尝试添加它。将它添加到模型后,慢慢引入更多列并刷新模型以确保视图仍然存在。您通常可以确定视图的哪个部分导致 EDM 问题。

【讨论】:

  • 您可能会发现,让其中一个视图列通过 EF 的密钥资格检查可能是一种首选的解决方案。见here
  • 我发现分组有时是个问题(似乎有点随机)。为了解决这个问题,我首先创建一个视图,选择 PK 和我想要的其他字段。然后我把它带入 edmx 模型。一旦我明白了,我就回到我的视图并添加分组。如果您没有对 PK 进行分组并且它是严格的 uid,我选择 MAX(PK) 以便满足 ID 要求。
【解决方案3】:

同样的问题,我所做的是在视图上添加 PrimaryKey,使用:

..... (SELECT      TOP (100) PERCENT ROW_NUMBER() OVER (ORDER BY R.Road DESC) AS RoadNumber......

然后我不得不对此进行 CAST:

ISNULL (CAST(RoadNumber AS INT),0)AS RoadNumber

该列必须是(非空),这就是 CAST 结尾的原因。

【讨论】:

  • 您的回答帮助我解决了问题。基本上,我视图中的所有字段都显示为可为空,因此我只是使用了您的 ISNULL 建议,因此实体框架会看到一些不可为空的列并选择这些列作为键。之后我就可以添加视图了。
  • 如此结合,我们得到:ISNULL (CAST(ROW_NUMBER() OVER (ORDER BY reportno ASC) AS INT),0)AS Id
【解决方案4】:

就我而言,这是因为 OUTER JOIN。
这会导致列可以为空并且不能由 EF 导入。

当我将其更改为 INNER JOIN 时,它起作用了。

另一种方法是使用ISNULL(见this post的答案)

【讨论】:

  • 这是给我的,感谢 aximili 救了我的加拿大熏肉
【解决方案5】:

为了能够将视图添加到模型中,实体框架需要数据库视图中的至少一列不可为空

【讨论】:

    【解决方案6】:

    检查您的视图是否确定在 *.edmx 文件中查看。

    正确:

    <EntitySet Name="SomeView" EntityType="Model.SomeView" store:Type="Views" Schema="dbo" />
    

    错误:

    <EntitySet Name="SomeView" EntityType="Model.SomeView" store:Type="Tables" Schema="dbo" />
    

    【讨论】:

      【解决方案7】:

      您可以向视图添加一个行数,使其看起来像一个不为空的键“Id”字段。一个例子:-

      SELECT DISTINCT
           -- dumb key for EF in C#
           IsNull(cast(ROW_NUMBER() OVER(PARTITION BY [Notes] ORDER BY [Notes] ASC) as int), 0) as [Id]
      
           -- required fields
          ,[Notes]        as [Notes]
          ,Count([Notes]) as [NoteCount]
      FROM
          [dbo].[Communication]
      GROUP BY
          [Notes]
      

      【讨论】:

        【解决方案8】:

        您在视图中添加的字段不是主键,实体是坏孩子

        【讨论】:

          【解决方案9】:

          我试图加载具有单个可为空列的视图。我的解决方案是将可空列包装在 isnull 中并提供默认值为零:

          isnull([column], 0)
          

          【讨论】:

            【解决方案10】:

            这可能是关于这个主题的答案的组合,但我读过的所有内容似乎都没有提到这个特定的修复。 我的视图连接了三个表,并且我遇到了上述错误。我从两个表中选择了 PK,但没有从第三个表中选择。加入第三张表中的PK后,实体框架就满足了。

            【讨论】:

              【解决方案11】:

              在您的视图中添加id 列:

              isnull(ROW_NUMBER() OVER (PARTITION BY e.CCT ORDER BY e.CCT), 0) AS Id
              

              之后,您可以在实体模型中添加您的视图。

              【讨论】:

                【解决方案12】:

                添加一个不为空的别名“id”的虚拟字段

                ...fields, 1 as id
                

                【讨论】:

                  【解决方案13】:

                  刚吃了这个,其他都没用。我已经用过几次了,主键 ID 技巧做到了。这次不行。 无奈之下,我将它们重写为存储过程,但仍然没有出现!

                  原因最终是 onedrive 在两台机器之间同步 sln 文件夹。我删除了.vs、bin和obj文件夹并重新编译,终于成功了。

                  【讨论】:

                  • 但这并不是具体导致和解决这个问题的原因。这可能会导致很多问题,您几乎可以在任何地方将其添加为答案。
                  • 是的,但如果它可以帮助其他人节省一些头发,我会投反对票。
                  • 哦,拜托,有十亿分之一的机会有人因为相同的原因犯了相同的错误。这意味着对于几乎每个人来说,这只是噪音,又是一个徒劳的答案。这个问题已经够吵了。
                  【解决方案14】:
                  1. 使用主键字段创建支持表并仅插入一条记录。
                  2. 创建视图并加入该表的已创建列(键)。
                  3. 现在您可以将视图添加到实体模型中。

                  【讨论】:

                  • GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[CUSTOM_DUAL]( [ID] [int] NOT NULL, CONSTRAINT [PK_TBL_CUSTOM_DUAL] 主键集群([ID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
                  • 您可以编辑您的答案以包含所有内容吗?
                  猜你喜欢
                  • 1970-01-01
                  • 2015-12-05
                  • 2023-03-20
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-11-05
                  • 2011-09-09
                  • 2014-09-10
                  • 1970-01-01
                  相关资源
                  最近更新 更多