1

EF 4.3.1を使用していて、添付ファイルオブジェクトを作成し、そのバイナリデータを個別に保持したいと考えています。そこで、データベースにAttachmentsとAttachmentDataの2つのテーブルを作成しました。これがスクリーンショットまたはそれらの関係です。

そして、これが私のクラスです:

public class Attachment
{
    public int Id { get; set; }
    public string Name { get; set; }
    public AttachmentData Content { get; set; }
}

[Table("AttachmentData")]
public class AttachmentData
{
    public int Id { get; set; }
    public byte[] Data { get; set; }
}

public class AttachmentConfig : EntityTypeConfiguration<Attachment>
{
    public AttachmentConfig()
    {
        HasRequired(att => att.Content)
            .WithRequiredPrincipal()
            .WillCascadeOnDelete();

        Property(att => entity.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(entity => entity.Name).IsRequired();
    }
}

リポジトリパターンを使用してデータベースにアクセスします。

public class Repository
{
    private readonly Context _db = new Context(); 

    public Attachment Add(string fileName, byte [] data)
    {
        var att = new Attachment
                      {
                          Name = fileName,
                          Content = new AttachmentData {Data = data}
                      };

        _db.Documents.Add(att);
        _db.SaveChanges();

        return att;
    }

    public void Delete(int id)
    {
        /* Try to find in local context
         * otherwise exception might appear:
         * "An object with the same key already exists in the ObjectStateManager. 
         * The ObjectStateManager cannot track multiple objects with the same key."
         */
        var att = _db.Documents.Local
            .FirstOrDefault(a => a.Id == id) ?? new Attachment {Id = id};

        _db.Entry(att).State = EntityState.Deleted;            
        _db.SaveChanges();            
    }
}

添付ファイルを追加および削除できるかどうかを確認するための簡単なテストを作成しました。

public void Can_Add_And_Delete()
{
    const string fileName = "FileName.tst";
    var data = new byte[] {0, 1, 2, 3, 4, 5};

    /*************
    * Works fine *
    *************/
    var cont = new Context();
    var att1 = new Attachment
               {
                   Name = fileName,
                   Content = new AttachmentData {Data = data}
               };

    cont.Documents.Add(att1);
    cont.SaveChanges();

    cont.Documents.Remove(att1);
    cont.SaveChanges();

    /********************** 
    * Throws an exception *
    *********************** 
    * The operation failed: The relationship could not be changed because
    * one or more of the foreign-key properties is non-nullable. When a change 
    * is made to a relationship, the related foreign-key property is set to 
    * a null value. If the foreign-key does not support null values, a new 
    * relationship must be defined, the foreign-key property must be assigned
    * another non-null value, or the unrelated object must be deleted. 
    */

    var repo = new Repository();
    var att2 = repo.Add(fileName, data);
    repo.Delete(att2.Id);
}            

スローされた例外の詳細な説明から、問題がコンテキスト内のAttachmentDataエンティティの存在によって引き起こされていることは明らかです。しかし、添付ファイルの状態が削除に設定されると(1対1の関係が構成されているため)、コンテキストはAttachmentDataを削除するのに十分賢いと思いました。そうでない場合、WillCascadeOnDelete()メソッドを使用する意味は何ですか?それは適切なdb関係の生成のためだけであり、C#側はそれの利点を得ることができませんか?

4

0 に答える 0