0

これは、EF6で機能するようになったこの質問の拡張です。ただし、共有プロパティと非共有プロパティの両方を持つサブクラスがある場合、問題があるようです。

これが私のモデル設定だとしましょう:

public abstract class Document
{
    public int Id { get; set; }
    public string NameOnDocument { get; set; }
}

public class BirthCertificate : Document
{
    public string RegistrationNumber { get; set; }
}

public class Licence : Document
{
    public string LicenceNumber { get; set; }
}

データベースでは、同じ列を共有したいBirthCertificate.RegistrationNumberと考えています。そのため、次のようにモデルを設定しています。Licence.LicenceNumberNumber

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    // Document - base class
    modelBuilder.Entity<Document>().HasKey(d => d.Id);
    modelBuilder.Entity<Document>()
        .Property(d => d.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    modelBuilder.Entity<Document>()
        .Property(d => d.NameOnDocument)
        .HasColumnName("Name");

    // Birth certificate
    modelBuilder.Entity<Document>().Map<BirthCertificate>(map => 
        map.Property(c => c.RegistrationNumber).HasColumnName("Number"));

    // Licence
    modelBuilder.Entity<Document>().Map<Licence>(map => 
        map.Property(l => l.LicenceNumber).HasColumnName("Number"));
}

データベースを生成すると、すべてが期待どおりに見え、機能します。

DB モデル

さて、当面の問題です。Licenceエンティティが有効期限も記録する必要があるとしましょう。だから私は次のようにそれを追加します:

public class Licence : Document
{
    public string LicenceNumber { get; set; }
    public DateTime ExpiryDate { get; set; }
}

データベースを再生成すると、次のようになります。

ここに画像の説明を入力

さらに、免許証と出生証明書を挿入しようとすると、次の例外が発生します。

タイプ 'System.Data.Entity.Infrastructure.DbUpdateException' の未処理の例外が EntityFramework.dll で発生しました

追加情報: エンティティまたは関連付け間で共有される値は、複数の場所で生成されます。マッピングによって、EntityKey がストアで生成された複数の列に分割されないことを確認します。

データベースが役に立たないため、その例外が発生する理由を理解できます。

私は何を逃したのですか?

4

2 に答える 2

0

データベースで 2 列を 1 列にすることで多くのメリットが得られるかどうかはわかりません。両方のドキュメントに1つあるとしても、多くのスペースを節約できずNumber、 baseの を調べることができないと思います。フィールドをベースにDocument追加し、オーバーライドでデータ注釈を使用することを検討しましたか?このようなものですか?Number

public abstract class Document
{
    public int Id { get; set; }
    public string NameOnDocument { get; set; }
    public virtual string Number
}

public class BirthCertificate : Document
{
    [Display(Name="Registration Number"]
    [Required]
    public override string Number { get; set; }
}

public class Licence : Document
{
    [Display(Name="Licence Number"]
    [Required]
    public override string Number { get; set; }
}

EDITそして、すべてのドキュメントに番号が付けられていない場合:

public abstract class Document
{
    public int Id { get; set; }
    public string NameOnDocument { get; set; }
}

public abstract class NumberedDocument : Document
{
    public virtual string Number
}

public class BirthCertificate : NumberedDocument
{
    [Display(Name="Registration Number"]
    [Required]
    public override string Number { get; set; }
}
于 2014-11-13T10:56:46.347 に答える
0

さて、問題は簡単に解決できることがわかりましたが、私が知る限り、どこにも文書化されていません。うまくいけば、これは同じ問題を抱えている人に役立ちます。

一見、重要なのは、派生エンティティのすべてのプロパティをマップする必要があることです

modelBuilder.Entity<Document>().Map<Licence>(map =>
{
    map.Property(l => l.LicenceNumber).HasColumnName("Number");
    map.Property(l => l.ExpiryDate).HasColumnName("ExpiryDate");
});

今、私のデータベースは期待どおりに生成され、すべてがうまくいっています。

于 2014-11-13T04:17:50.547 に答える