为什么我不能在Entity Framework 4.0中使用包含Union的View?

时间:2011-06-27 15:09:57

标签: entity-framework view union

我有一个与此类似的视图:

SELECT Id, Name
FROM Users
UNION ALL
SELECT NULL as [Id], NULL as [Name]

当我尝试在Entity Framework中映射到此视图时,它只是失败了。我没有收到错误,但我的数据存储中不存在该视图。为什么是这样?有办法吗?

4 个答案:

答案 0 :(得分:15)

我知道这是一个已经标记为已回答的旧问题,但我想发布另一种编辑edmx的方法。经过大量的谷歌搜索并将我的头发拉了几个小时后,我尝试了不同的选择......我很努力地学到了这一点......

对于视图,EF会尝试通过标识不可为空的列来推断主键 和非二进制(见Create an Entity Key When No Key Is Inferred)。

使用用于展平相关数据以进行查找的视图,这可能导致许多列(或错误的列)被推断为键。

对于具有UNION的视图,它可能会导致相反的问题,因为可能没有可以安全地包含为密钥的真实标识列。

要强制EF将列标识为键,可以使用ISNULL()来确保该值不可为空:ISNULL(column_name, replacement_value)

要强制EF不将列标记为键,可以使用NULLIF()使其可为空:NULLIF(column_name, value_not_equal_to_parameter_1)

如果您需要确保返回一个值,但又不想将其标记为键,我相信COALESCE(column_name, replacement_value)将完成ISNULL的工作而不用EF将该列标记为键

如果确实没有可用的列可用作为主键(如在UNION视图中),则可以通过使用ISNULL()与ROW_NUMBER()结合来伪造不可为空的PK在SELECT语句中:SELECT ISNULL(ROW_NUMBER() OVER (ORDER BY sort_criteria), 0) as 'ALIASNAME'

作为替代方案,edmx绝对可以像Marcos Prieto建议的那样直接进行编辑,但是下次运行“从数据库更新模型”时,您可能会有覆盖这些更改的风险。

希望这有助于将来遇到此事的任何人!

答案 1 :(得分:2)

这是因为Visual Studio无法推断视图的主键。 您可以通过使用XML编辑器打开它来查看edmx文件中的错误消息,并查看SSDL部分。 这是我的模型产生的错误消息(我在我的数据库中创建了一些像你一样的视图来模拟):

Errors Found During Generation:
warning 6013: The table/view 'PhoneBook.dbo.ContactCustomer' does not have 
a primary key defined and no valid primary key could be inferred.
This table/view has been excluded. To use the entity, 
you will need to review your schema, 
add the correct keys, and uncomment it.

在EF 4中不支持Union。 但我认为问题在于Visual Studio将您的视图视为奇怪的视图。

您可以通过创建另一个View并进行比较来进行一些实验(使用模型设计器中数据库菜单中的更新模型)。

您可以手动修改模型(手动输入edmx文件)以定义主键来解决此问题。

答案 2 :(得分:2)

我的观点非常完美。我修改了它(更改了2个表的并集上的视图),从数据库更新了模型,出现了这个问题。

我分3步修好:

  1. 使用XML编辑器打开.edmx文件。
  2. 取消注释视图的EntityType XML(edmx:StorageModels> Schema)代码并添加密钥:

    <EntityType Name="your_view">
       <Key>
          <PropertyRef Name="your_id" />
       </Key>
       <Property Name="your_id" Type="int" Nullable="false" />
       <Property Name="other_field" Type="varchar" MaxLength="45" />
    </EntityType>
    
  3. 确保EF没有删除edmx中的视图:StorageModels&gt;架构&gt; EntityContainer(如果你有代码库,从那里复制代码):

    <EntitySet Name="your_view" EntityType="Your_Model.Store.your_view" store:Type="Views" store:Schema="your_schema" store:Name="your_view">
        <DefiningQuery>SELECT
           `your_view`.`your_id`, 
           `your_view`.`other_field`, 
            FROM `your_view` AS `your_view`
        </DefiningQuery>
    </EntitySet>
    

答案 3 :(得分:0)

我知道这是一个老问题,但我最近遇到了这个问题。在尝试执行上述方法之后,我只是创建了另一个从Union视图中选择的视图。我能够通过更新我的实体模型来映射新视图。