3

私の人生のためにこれを理解することはできません。MSDNの記事は明確ではなく、古くなっているようです。私はEF5を使用しており、次のように一方向の関係を設定しようとしています。これが私がこれまでに持っているものです。

public sealed class Capture {
    /// <summary>
    /// Get and Set Capture's Unique Identifier.
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Get and Set Capture's Operating System.
    /// </summary>
    public OperatingSystem OperatingSystem { get; set; }
}

public sealed class OperatingSystem {
    /// <summary>
    /// Operating System's Unique Identifier.
    /// </summary>
    public int Id { get; set; }
}

internal sealed class EntityCaptureConfiguration : EntityTypeConfiguration<Capture> {
    /// <summary>
    /// Create an Entity Capture Configuration.
    /// </summary>
    public EntityCaptureConfiguration() {
        this.ToTable("Capture");
        this.HasKey(m => m.Id);

        this.Property(m => m.Id).HasColumnName("Id");

        this.HasRequired(m => m.OperatingSystem).WithRequiredDependent().Map(m => {
            m.ToTable("OperatingSystem");
            m.MapKey("OperatingSystemId");
        });
    }
}

コンパイルして実行すると、次のランタイム例外が発生します。 "エラー3034:16、46行目から始まるフラグメントのマッピングで問題が発生しました:キーが異なる可能性のある2つのエンティティが同じ行にマッピングされています。これら2つのマッピングフラグメントがAssociationSetの両端をマッピングしていることを確認してください対応する列に。

2つの特定のキーを使用してこれらの2つのテーブルを結合したいことを示す明確な方法が文字通りないことに気づかずにはいられません。親テーブルの結合に使用する子テーブルのキーをどこで指定するのですか?

これが私が助けを必要としているものです:

  1. 「 OperatingSystemId 」という名前のキャプチャタイプのプロパティを公開したくありません。「OperatingSystem」プロパティで十分です。

  2. Captureタイプ とOperatingSystemタイプの間に双方向の関係は必要ありません。CaptureからOperatingSystemへの一方向の関係のみが必要です。

  3. データベースのオペレーティングシステムテーブルに「CaptureId 」という名前の列を作成したくありません。なぜそれが必要なのかさえ分かりませんが、そのようにすることを提案している記事をどこかで読みました。

  4. 生成されるSQL結合は、OUTERJOINではなくINNERJOINである必要があります。

  5. CaptureタイプのOperatingSystemプロパティを仮想として定義する必要が本当にありますか?このプロパティを遅延ロードしたくありません。

  6. ボーナスは、私が完全に迷子になっているので、この例外を私に説明できる誰かを指しています。Google検索はFluentAPIには絶望的です。デザイナーを使っているとヒット数が多いのですが、すべての結果がモデルの再生成を示唆しているので、関係ないと思いますが、ここでは当てはまらないと思います。

更新: 私はおそらくこれについてはっきりしていませんでした。SQLServerでデータベースモデルを既に設定しています。デザイナを使用せずに、既存のデータベースモデルに対してFluentAPIを使用してEFコンテキストを構成する方法を理解しようとしています。デザイナを使用する場合は、データベースからコンテキストを生成するようにデザイナに依頼できることを理解しています。それは私が望んでいることではありません。そして、その理由に興味がある人のために-FluentAPIを使用してそれを行う方法を理解したいからです。

Update2: つまり、私が設定したものと同じように、クエリでナビゲーションプロパティにフィルターを指定すると、EFは結合を正しく生成します。これを行わないと、クエリで結合が生成されません。とにかく、ナビゲーションプロパティはまだ入力されていません!

よろしくお願いします。

4

1 に答える 1

10

したがって、私のようなORMをあまり使用しておらず、MyBatisなどのデータマッパーを使用した経歴がある場合、私の質問の例を考えると、解決策はこれです。

まず、エンティティタイプを封印済みとして宣言することはできず、関連付けに参加するプロパティは仮想として宣言する必要があります。これは、EFが実行時に動的プロキシを使用して型を拡張し、動的プロキシを使用してプロパティをオーバーライドして遅延読み込みを有効にするためです。

public class Capture {
    /// <summary>
    /// Get and Set Capture's Unique Identifier.
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Get and Set Capture's Operating System.
    /// </summary>
    public virtual OperatingSystem OperatingSystem { get; set; }
}

public class OperatingSystem {
    /// <summary>
    /// Operating System's Unique Identifier.
    /// </summary>
    public int Id { get; set; }
}

これを行わない場合、エラーはスローされませんが、EFは関連するプロパティを常にnullとして設定します。

次に、関連付けられたプロパティがまだマッピング用に構成されていない場合を除き、特定のテーブルにマップしないでください。EFは、同じテーブルが基本的に2回マップされていると文句を言います。私の例では、すでにOperatingSystemタイプを独自にマッピングしており、関連付けを設定するときに、再度マッピングしていました。

internal sealed class EntityCaptureConfiguration : EntityTypeConfiguration<Capture> {
    /// <summary>
    /// Create an Entity Capture Configuration.
    /// </summary>
    public EntityCaptureConfiguration() {
        this.ToTable("Capture");
        this.HasKey(m => m.Id);

        this.Property(m => m.Id).HasColumnName("Id");

        this.HasRequired(m => m.OperatingSystem).WithRequiredDependent().Map(m => m.MapKey("OperatingSystemId"));
    }
}

最後に、エンティティタイプを完全に封印済みとして宣言する必要があり、プロパティを仮想として宣言したくない場合(封印されたタイプではとにかくできません)、コンテキストの構成でプロキシと遅延読み込みを無効にします。

public sealed class EntityDefaultContext : DbContext {    
    /// <summary>
    /// Model Creating Event Handler.
    /// </summary>
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        var entityCaptureConfiguration = new EntityCaptureConfiguration();
        var entityOperatingSystemConfiguration = new EntityOperatingSystemConfiguration();

        modelBuilder.Configurations.Add(entityOperatingSystemConfiguration);
        modelBuilder.Configurations.Add(entityCaptureConfiguration);

        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }
}

それはすべての人々です。これが将来私のような人に役立つことを願っています。

于 2012-10-21T22:46:17.460 に答える