How to identify nested identity relationships first.

First, I use the EF5 code in a simple test application to test various functions. I have defined an “identifying relationship” between two objects, which are a one-to-many link. Here I define a PhotoCollection that has many child Photo objects,

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() { } } 

and my implementation of OnModelCreating includes:

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

As a result, when I delete the PhotoCollection, all the objects in the photo are also deleted, which is ensured by the “relationship identification”. Excellent.

My question is how to define the next level in this graph of objects , let's say I want PhotoProperties to be a one-to-many collection from Photos. In this case, I would like to delete PhotoCollection, and all the corresponding Photo and PhotoProperty entries will also be deleted. Using the above approach, is it necessary to add the GrandParent property to PhotoProperty pointing to PhotoCollection?

Can I achieve the same result with free Api in the model builder?

The only examples I managed to find on the Internet are hierarchical child hierarchies of the same level.

Thanks in advance.

+4
source share
1 answer

In my opinion, this should work:

 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; } //... } 

Note that PhotoCollectionId in PhotoProperty not related to PhotoCollection , but is part of the composite foreign key (PhotoCollectionId,PhotoId) that refers to Photo .

And yes, you can define all mapping to the 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); 
+8
source

Source: https://habr.com/ru/post/1441591/


All Articles