What am I doing wrong with my relationship? General entity referenced by two dependent objects

I am having problems defining a foreign key relationship in an entity structure. I have welded the code to a minimum to demonstrate the problem.

The model is defined as:

public class AccessControlList { [Key] public int Id { get; set; } public string Name { get; set; } } public class ManagedFile { [Key] public int Id { get; set; } public string Name { get; set; } public virtual AccessControlList AccessControl { get; set; } } public class ManagedFolder { [Key] public int Id { get; set; } public string Name { get; set; } public virtual AccessControlList AccessControl { get; set; } public virtual ISet<ManagedFile> Files { get; private set; } public ManagedFolder() { Files = new HashSet<ManagedFile>(); } } 

Thus, essentially, I have a single AccessControl object that can be referenced by either a ManagedFile object or a ManagedFolder.

To make sure the foreign key is added to the ManagedFile and ManagedFolder, I added the following smooth display

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); modelBuilder.Entity<ManagedFile>() .HasRequired(mf => mf.AccessControl) .WithRequiredDependent() .Map(m => m.MapKey("AccessControlListId")); modelBuilder.Entity<ManagedFolder>() .HasRequired(mf => mf.AccessControl) .WithRequiredDependent() .Map(m => m.MapKey("AccessControlListId")); base.OnModelCreating(modelBuilder); } 

This creates a database that looks exactly as I expect, with the AccessControlListId foreign key for each of the ManagedFile and ManagedFolder.

Entity Framework Created Schema

Everything looks good to me, but when I try to insert some data using this code

 using(var ctx = new MyContext()) { var mf = ctx.Folders.Add(new ManagedFolder {Name = "$/"}); mf.AccessControl = new AccessControlList(); var file = new ManagedFile {Name = "myfile.txt"}; mf.Files.Add(file); file.AccessControl = new AccessControlList(); ctx.SaveChanges(); } 

It gives an error ...

Error

I can’t understand what I did, what’s wrong?

Since I understand my mapping, EF can save a new AccessControlList and then use the Id to write the ManagedFolder or ManagedFile table.

As always, I appreciate any help offered.

Thanks Andy

+4
source share
1 answer

Why does the database look “exactly as you expect”? Apparently you are trying to define two one-to-one relationships ( .HasRequired(...).WithRequiredDependent(...) ), but your database relationships are one-to-many.

Do you need a one-to-one relationship to one? In the latter case (which is simpler), simply replace the two WithRequiredDependent() WithMany() with WithMany() .

If you want one to one, you cannot define a separate foreign key AccessControlListId . You must use shared primary keys, i.e. PC dependent is FK at the same time. The display should be:

 modelBuilder.Entity<ManagedFile>() .HasRequired(mf => mf.AccessControl) .WithRequiredDependent(); // the same for ManagedFolder 

... without MapKey .

+5
source

All Articles