2017-01-24 4 views
1

私は奇妙な問題の魔女EF Core 1.1に直面しています。いくつかのエンティティをタグ付けできるアプリケーションを作成しようとしています。したがって、リレーションテーブルリスト用の抽象ジェネリッククラスを作成しました。問題は、EFがFK(Idプロパティが動作する汎用抽象クラス)をサポートしていないようです。Entity Frameworkコアをサポートしない一般的な抽象エンティティとMeny2Menyの関係?

public abstract class TaggedEntityBase<T> : EntityBase 
{ 
    public ICollection<T> EntityTags { get; set; } 
    public List<Tag> Tags { get { return EntityTags?.Select(x => x.Tag).ToList(); } } 
} 

public class AddressTag 
{ 
    public long TagId { get; set; } 
    public Tag Tag { get; set; } 
    public long EntityId { get; set; } 
    public Address Entity { get; set; } 
} 

public class Address : TaggedEntityBase<AddressTag> 
{ 
    public string Street { get; set; } 
    public string City { get; set; } 
} 
public class Tag : EntityBase 
{ 
    public string Name { get; set; } 
    public virtual ICollection<AddressTag> AddressTags { get; set; } 
} 

モデルBuilderマッピング:

public DbSet<Address> Addresses { get; set; } 
    public DbSet<AddressTag> AddressTag { get; set; } 
    public DbSet<Tag> Tags { get; set; } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<AddressTag>() 
      .ToTable("AddressTag"); 

     modelBuilder.Entity<AddressTag>() 
      .HasKey(t => new { t.EntityId, t.TagId }); 
     modelBuilder.Entity<AddressTag>() 
     .HasOne(pt => pt.Entity) 
      .WithMany(p => p.EntityTags) 
      .HasForeignKey(p => p.EntityId); 
     modelBuilder.Entity<AddressTag>() 
     .HasOne(pt => pt.Tag) 
      .WithMany(p => p.AddressTags) 
      .HasForeignKey(p => p.TagId); 

    } 

はEFがタグ

タイプの未処理の例外を取得しようとするエラーがあり「システム

はこちらモデルです.Data.SqlClient.SqlException 'Microsoft.EntityFrameworkCore.dllで発生しました。追加情報:無効な列名' AddressId '。

私はそのId規則を持っていません。

注:Address POCO内に明示的にpublic ICollection<AddressTag> EntityTags { get; set; }を配置すると、EntityTags.Tagも含めて完全に動作します。 助けてくれてありがとう:

+0

は似問題があった – miechooy

+0

サンプルが不完全です。 'EntityBase'クラスがありません.' public List タグ{get {return EntityTags?.Select(x => x.Tag).ToList();} }} 'はコンパイルされません(' T'の制約がありません)。再現性を持たせるために不足している部品でポストを更新できますか? –

答えて

1

問題はジェネリックおよび/または抽象ベースのエンティティクラスとは関係ありません。

まず、あなたのサンプルモデルをコンパイルするために、私は次のクラスを追加しました

public abstract class EntityBase 
{ 
    public long Id { get; set; } 
} 

public abstract class EntityTagBase 
{ 
    public long TagId { get; set; } 
    public Tag Tag { get; set; } 
} 

は、次のようにAddressTagクラスを変更:

public class AddressTag : EntityTagBase 
{ 
    public long EntityId { get; set; } 
    public Address Entity { get; set; } 
} 

をし、許可するようにTaggedEntityBase<T>クラスにwhere T : EntityTagBase制約を追加しましたTagプロパティアクセッサー内Select(x => x.Tag)

これまでのところとても良いです。生成された移行のTag関連部分は次のようになります。

migrationBuilder.CreateTable(
    name: "Tags", 
    columns: table => new 
    { 
     Id = table.Column<long>(nullable: false) 
      .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 
     AddressId = table.Column<long>(nullable: true), 
     Name = table.Column<string>(nullable: true) 
    }, 
    constraints: table => 
    { 
     table.PrimaryKey("PK_Tags", x => x.Id); 
     table.ForeignKey(
      name: "FK_Tags_Addresses_AddressId", 
      column: x => x.AddressId, 
      principalTable: "Addresses", 
      principalColumn: "Id", 
      onDelete: ReferentialAction.Restrict); 
    }); 

AddressesテーブルにAddressId列とFKを参照してください?何故ですか?あなたのTags財産のため:

public List<Tag> Tags { get { return ...; } } 

それはおそらく読み取り専用のコレクションプロパティをマッピングの現在のEFコアのバグだが、正味の効果は、それはもちろん、あなたではありませんAddressTagの間には多くの関係に1を考慮することです意図。

一般に、エンティティモデルをきれいに保つことと、そのような「ヘルパー」プロパティ(コレクションと参照型の両方)を含めないことをお勧めします。ナビゲーションプロパティのように見えますが、クエリ内で誤って使用するのは簡単です。実行計画が完全に変更され、予期しない例外や誤った結果が発生します(基本プロパティがロードされていない場合)。 Listを返すプロパティを作成しないという一般的なルール違反については、クラスのメンバーではなく、すべてのプロパティアクセス呼び出しで作成されます。

まもなく、そのプロパティを削除するだけで、問題はなくなります。あなたはそれを維持すると主張している場合や、その後NotMappedデータアノテーションでそれを飾る:

[NotMapped] 
public List<Tag> Tags { get { return ...; } } 
+0

あなたはまったく正しいです。私は誤ってあなたの投稿の前にそれを理解しましたが、今はなぜそれがAddressIdなのかを理解しています。マッピングを無視するだけです。ありがとう –

関連する問題