3

データベース内のエンティティとの関係が不明な多くの異なるドキュメントを含むエンティティがあります。

public class Document : BaseEntity
{

    public string Filename { get; set; }

    public string MIMEType { get; set; }
    public int? Length { get; set; }

    public byte[] Content { get; set; }

}

codefirst-mappingは次のとおりです。

    public DocumentConfiguration()
    {
        Property(x => x.Filename).HasMaxLength(300).IsRequired();
        Property(x => x.MIMEType).HasMaxLength(300).IsRequired();
        Property(x => x.Length).IsOptional();
        Property(x => x.Content).IsOptional().HasColumnType("varbinary(max)");


        ToTable("Document"); 
    }

ここで、次のように、アドレス内のdocument-tableへのオプションの関係が必要です。

public class Address : BaseEntity
{

    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Additional { get; set; }


    public string Street { get; set; }
    public string HousNr { get; set; }
    public string ZipCode { get; set; }
    public string City { get; set; }

    public virtual Document Image { get; set; }

}

次のマッピングを使用します。

    public AddressConfiguration()
    {

        Property(x => x.Name1).IsRequired().HasMaxLength(250);
        Property(x => x.Name2).HasMaxLength(250);
        Property(x => x.Additional).HasMaxLength(250);


        Property(x => x.Street).HasMaxLength(250);
        Property(x => x.HousNr).HasMaxLength(10);
        Property(x => x.ZipCode).HasMaxLength(10);
        Property(x => x.City).HasMaxLength(100);


        HasOptional(x => x.Image)
            .WithOptionalDependent()
            .Map(map => map.MapKey("ImageId")).WillCascadeOnDelete();


        ToTable("Address");

    }

しかし、ドキュメントテーブルの画像を削除すると、関連するアドレスが削除されます。

OneWay-アドレスからドキュメントへの削除を希望しますが、ドキュメントからアドレスへの削除は希望しません...?

どうすればそれを実装できますか?

ありがとうございました。

4

2 に答える 2

5

ドキュメントからアドレスへのカスケードがある理由は、WithOptionalDependentメソッドを使用したためです。ドキュメントから:

リレーションシップを optional:optional に構成します。リレーションシップの反対側にナビゲーション プロパティはありません。構成されているエンティティ タイプは従属であり、プリンシパルへの外部キーが含まれています。リレーションシップが対象とするエンティティ タイプは、リレーションシップのプリンシパルになります。

AddressConfiguration メソッドの次のコード行を検討してください。

HasOptional(x => x.Image)         // The entity type being configured is Address
   .WithOptionalDependent()...   // The entity type that the relationship targets
                                //  is Document (x.Image)

つまり、この関連付けでは Address を従属として、Document をプリンシパルとして効果的に指定するため、カスケード動作が行われます。

しかし、待ってください。この話には続きがあります。1 対 1 の関連付けを作成するには、2 つの方法があります。最初はShared Primary Key AssociationまたはOne-to-One Foreign Key Associationです。詳細については、こちらこちらをご覧ください。外部キー (1 対 1 の外部キー アソシエーション) を介してアソシエーションをマップしたいようです。その場合、依存エンティティは常に外部キーを保持することに注意する必要があります。つまり、この場合、Document エンティティには、Address エンティティの AddressId を参照する AddressId が含まれます (逆を行ったのは正しくありません)。

つまり、オブジェクト モデルと流暢な API コードは次のようになります。

public class Address 
{
    public int AddressId { get; set; }
    public virtual Document Image { get; set; }
}

public class Document 
{
    public int DocumentId { get; set; }
}

class Context : DbContext
{
    public DbSet<Address> Addresses { get; set; }
    public DbSet<Document> Documents { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Address>()  // The entity being configured is Address
                    .HasOptional(x => x.Image)  
                    .WithOptionalPrincipal()
                    .Map(map => map.MapKey("AddressId"))
                    .WillCascadeOnDelete();
    }
}

基本的にWithOptionalPrincipalは、使用する必要があるメソッドです。

リレーションシップを optional:optional に構成します。リレーションシップの反対側にナビゲーション プロパティはありません。構成されているエンティティ タイプは、関係のプリンシパルになります。リレーションシップが対象とするエンティティ タイプは従属であり、プリンシパルへの外部キーが含まれます。


その結果、アドレスからドキュメントへのカスケード削除が適切にオンになります。

于 2012-04-05T18:59:54.410 に答える
0

OneToManyCascadeDeleteConvention を削除してみてください: modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention >();

于 2012-04-04T13:54:18.183 に答える