0

I'm using a model produced with Devart Entity Developer (.edml file, which I understand is mostly similar to .edmx) to generate Entity classes whose relations are initialized in a DbContext class. The database schema specifies no PK for View1, and all columns are nullable. But the code generation assumes that for views lacking a primary key, all columns are the key. I.e., the .ssdl has all columns under the Key element and the DbContext has .IsRequired() specified on all, like so:

ssdl excerpt:

...
<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>
....

From 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");

This causes a NullReferenceException when querying would return a row with one of the PK columns having null value.

Is there a way to represent a view in EF without specifying keys or altering the database schema? I've found this: http://elegantcode.com/2012/03/15/querying-entityframework-views-without-a-key/

Is this the preferred solution? I suppose I could use DefiningQuery as well, but this seems to duplicate the sql that was used to generate the view?

4

2 に答える 2

1

次の手順を実行する必要があります。

  1. エンティティのすべての列について、モデルの概念部分とストレージ部分でエンティティ キー プロパティを False に設定します。
  2. モデルの概念部分のエンティティに文字列型の Id プロパティを追加し、エンティティ キーの値を True に設定します。
  3. 概念パーツとストレージ パーツの同期をオンにしている場合 ([モデル設定ダイアログ] -> [同期] -> [マッピング])、Id 列がストレージ パーツの既存のエンティティに自動的に追加されます。この列の Type=ROWID および Name=ROWID を設定する必要があります。マッピングは自動的にカスタマイズされます。同期がオフの場合は、ストレージ部分の対応するエンティティに ROWID 列を追加し、Type=ROWID に設定します。その後、クラスのコンテキスト メニューを呼び出し、[マッピングの詳細] 項目を選択し、表示されたダイアログで有効な列マッピングを指定します。
  4. クラスの他のプロパティについては、Nullable を True に設定します。

編集項目3:ストレージ部分のエンティティの列名はROWIDでなければならない

于 2012-06-27T07:36:34.457 に答える
0

デザイナーで edml を開き、エンティティに手動で主キーを設定することにより、devart EF プロバイダーの oracle ビューに対して主キーを確立できます (ビューが定義したキーに対して一意のデータを返すことを保証できる場合)。次に (これが機能する秘訣です) モデル エクスプローラー ウィンドウに移動し、モデルのストア部分に同じ変更を加えます。通常、ビューを EF モデルのデザイン サーフェイスにドラッグすると、devart は定義されていないビューの主キーを推測しようとします。繰り返しますが、ビューが定義したキーに対して一意のデータを返すことが重要です。

于 2012-06-27T02:17:01.313 に答える