0

我正在使用使用 Devart Entity Developer 生成的模型(.edml 文件,我理解它与 .edmx 最相似)来生成实体类,其关系在 DbContext 类中初始化。数据库架构没有为 View1 指定任何 PK,并且所有列都可以为空。但是代码生成假定对于缺少主键的视图,所有列都是键。即, .ssdl 具有 Key 元素下的所有列,并且 DbContext 具有在 all 上指定的 .IsRequired() ,如下所示:

ssdl摘录:

...
<EntityType Name="View1">
  <Key>
    <PropertyRef Name="FirstCol" />
    <PropertyRef Name="Col2" />
    <PropertyRef Name="LastCol" />
  </Key>
  <Property Name="FirstCol" Type="VARCHAR2" Nullable="false" MaxLength="4000" />
  <Property Name="Col2" Type="VARCHAR2" Nullable="false" MaxLength="120" />
  <Property Name="LastCol" Type="VARCHAR2" Nullable="false" MaxLength="20" />
</EntityType>
....

来自 DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{     
  #region View1
  modelBuilder.Entity<View1>()
    .HasKey(p => new { p.FirstCol, p.Col2, p.LastCol})
      .ToTable("View1", "Owner");
        // Properties:
        modelBuilder.Entity<View1>()
          .Property(p => p.FirstCol)
            .HasColumnName("FirstCol")
            .IsRequired()
            .HasMaxLength(4000)
            .HasColumnType("VARCHAR2");
        modelBuilder.Entity<View1>()
          .Property(p => p.Col2)
            .HasColumnName("Col2")
            .IsRequired()
            .HasMaxLength(120)
            .HasColumnType("VARCHAR2");
        modelBuilder.Entity<View1>()
          .Property(p => p.LastCol)
            .IsRequired()
            .HasMaxLength(20)
            .HasColumnType("VARCHAR2");

这会导致 NullReferenceException,当查询将返回具有空值的 PK 列之一的行时。

有没有办法在 EF 中表示视图而不指定键或更改数据库架构?我发现了这个:http ://elegantcode.com/2012/03/15/querying-entityframework-views-without-a-key/

这是首选的解决方案吗?我想我也可以使用 DefiningQuery,但这似乎重复了用于生成视图的 sql?

4

2 回答 2

1

您应该执行以下步骤:

  1. 对于实体的所有列,在模型的概念和存储部分中将 Entity Key 属性设置为 False。
  2. 将字符串类型的 Id 属性添加到模型概念部分的实体中,并将​​其 Entity Key 值设置为 True。
  3. 如果您打开了概念部分和存储部分的同步(模型设置对话框->同步->映射),则 Id 列将自动添加到存储部分中的现有实体中。您应该为此列设置 Type=ROWID 和 Name=ROWID。映射将自动自定义。如果不同步,则将ROWID列添加到存储部分的对应实体中,并为其设置Type=ROWID。之后,调用类的上下文菜单,选择 Mapping Details 项并在显示的对话框中指定有效的列映射。
  4. 对于类的其他属性,将 Nullable 设置为 True。

编辑项3:存储部分实体的列名必须为ROWID

于 2012-06-27T07:36:34.457 回答
0

您可以通过在设计器中打开 edml 并手动设置实体上的主键,针对 devart EF 提供程序中的 oracle 视图建立主键(假设您可以保证视图返回您定义的键的唯一数据)。然后(这是使这项工作起作用的技巧)转到模型资源管理器窗口并对模型的存储部分进行相同的更改。通常,如果您只是将视图拖到 EF 模型的设计图面上,devart 将尝试推断未定义的视图的主键。同样,您的视图为您定义的键返回唯一数据至关重要。

于 2012-06-27T02:17:01.313 回答