启用了级联删除的实体框架1到1

时间:2012-07-10 12:51:50

标签: entity-framework entity-framework-4 cascading-deletes

我正在使用EF 4.3.1,并希望创建一个附件对象并分别保留其二进制数据。所以,我在数据库中创建了两个表:Attachments和AttachmentData。这是screenshot或他们的关系。

以下是我的课程:

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实体的存在引起的。但是我认为一旦将Attachment状态设置为删除(因为配置了1对1关系),上下文就足以智能删除AttachmentData。如果不是这样,那么使用WillCascadeOnDelete()方法有什么意义呢?是仅仅为了正确的数据库关系生成而C#端无法获得它的任何好处?

0 个答案:

没有答案