【问题标题】:How to define nested Identifying Relationships Entity Framework code first如何首先定义嵌套的识别关系实体框架代码
【发布时间】:2012-10-23 15:26:14
【问题描述】:

我现在首先在一个简单的测试应用程序中使用 EF5 代码来测试各种功能。我已经定义了代表一对多链接的两个实体之间的“识别关系”。这里我定义了一个有很多子 Photo 实体的 PhotoCollection;

public class PhotoCollection
{
    public int Id { get; set; }
    public virtual ISet<Photo> Photos { get; private set; }

    public PhotoCollection()
    {
        Photos = new HashSet<Photo>();
    }
}

public class Photo
{
    [Key, ForeignKey("Parent"), Column(Order = 1)]
    public int PhotoCollectionId { get; set; }

    [Key, Column(Order = 2)]
    public int PhotoId { get; set; }

    public virtual PhotoCollection Parent { get; set; }


    [Required, MaxLength(200)]
    public string FilePath { get; set; }

    public Photo()
    {
    }

}

我的 OnModelCreating 实现包括;

modelBuilder.Entity<Photo>().Property(p => p.PhotoId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

结果是,当我删除 PhotoCollection 时,所有照片实体也会被删除,这是由“识别关系”提供的。太好了。

我的问题是如何在此对象图中定义更深层次,假设我想将 PhotoProperties 作为 Photo 的一对多集合。在这种情况下,我想删除 PhotoCollection,所有适当的 Photo 和 PhotoProperty 记录也将被删除。使用上面的方法,是否有必要向 PhotoProperty 添加指向 PhotoCollection 的 GrandParent 属性?

我可以在模型构建器中使用 fluent Api 实现相同的结果吗?

我设法在网上找到的唯一示例是单级父>子层次结构。

提前致谢。

【问题讨论】:

    标签: ef-code-first entity-relationship one-to-many entity-framework-5


    【解决方案1】:

    在我看来这应该可行:

    public class Photo
    {
        [Key, ForeignKey("Parent"), Column(Order = 1)]
        public int PhotoCollectionId { get; set; }
    
        [Key, Column(Order = 2)]
        public int PhotoId { get; set; }
    
        public virtual PhotoCollection Parent { get; set; }
    
        public virtual ISet<PhotoProperty> PhotoProperties { get; private set; }
    
        //...
    }
    
    public class PhotoProperty
    {
        [Key, ForeignKey("Parent"), Column(Order = 1)]
        public int PhotoCollectionId { get; set; }
    
        [Key, ForeignKey("Parent"), Column(Order = 2)]
        public int PhotoId { get; set; }
    
        [Key, Column(Order = 3)]
        public int PhotoPropertyId { get; set; }
    
        public virtual Photo Parent { get; set; }
    
        //...
    }
    

    请注意,PhotoProperty 中的 PhotoCollectionId 不引用 PhotoCollection,而是引用 Photo 的复合外键 (PhotoCollectionId,PhotoId) 的一部分。

    是的,您可以使用 Fluent API 定义整个映射:

    modelBuilder.Entity<PhotoCollection>()
        .HasMany(pc => pc.Photos)
        .WithRequired(p => p.Parent)
        .HasForeignKey(p => p.PhotoCollectionId);
    
    modelBuilder.Entity<Photo>()
        .HasKey(p => new { p.PhotoCollectionId, p.PhotoId });
    
    modelBuilder.Entity<Photo>()
        .Property(p => p.PhotoId)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    
    modelBuilder.Entity<Photo>()
        .HasMany(p => p.PhotoProperties)
        .WithRequired(pp => pp.Parent)
        .HasForeignKey(pp => new { pp.PhotoCollectionId, pp.PhotoId });
    
    modelBuilder.Entity<PhotoProperty>()
        .HasKey(pp => new { pp.PhotoCollectionId, pp.PhotoId, pp.PhotoPropertyId });
    
    modelBuilder.Entity<PhotoProperty>()
        .Property(pp => pp.PhotoPropertyId)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    

    【讨论】:

    • 这很有帮助。你知道有什么好的文档吗?我正在尝试为 Azure 移动服务和 Azure SQL 做类似的事情。
    猜你喜欢
    • 1970-01-01
    • 2011-07-28
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    相关资源
    最近更新 更多