Entity Framework 6 and Collections

I am developing my first entity application. I am using EF vesion 6 (from Nuget) and .net 4.0. However, I have some difficulties with something that seems to me to be unusually simple. I found a lot of conflicting tips and solutions on the Internet, but after spending a few days trying to figure it out, I'm really confused and thoroughly interrogate some of the basic understandings that I have in the Entity Framework. I want to do the following: create a simple set of related objects and automatically delete them when they are removed from the parent.

Here is how I can simulate this in C # vanilla. According to Microsoft samples, suppose we have two classes: Post and Tag, for example:

public class Post { public string Name { get; set; } public string Author { get; set; } public ICollection<Tag> Tags { get; set; } } public class Tag { public string Text { get; set; } // Possibly other properties here } 

Then adding the tag is as simple as myPost.Tags.Add(myTag) , and removing the tag is as simple as myPost.Tags.Remove(myTag) .

Now, towards the essence of the Entity Framework: I looked at it and thought, β€œForeign Key, of course!”. but I had a lot of problems with adding FK: the tags were not deleted from the database when they were removed from the message, myPost.Tags would have 0 elements when loading from db, despite the fact that SQL explorer showed that the PostId value was correct etc. I went astray with a bunch of tricks, for example, tagged Tag.PostId as a key, manually deleting the tags, actually adding the tag to the context as DbSet, manually setting myTag.Post = null; (I tried with Lazy to load both on and off, for what it's worth - although I would like it to be possible, if possible)

Now (thanks in no small measure to the seemingly conflicting and overly complex examples), I am very confused and lost. Can someone tell me how should I tune this relationship in EF? (By the way, I'm using Code First)

DECISION:

Thanks to Moho, I came up with this structure that does exactly what I want:

 public class Post { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public virtual ICollection<Tag> Tags { get; set; } public Post() { Tags = new HashSet<Tag>(); } } public class Tag { [Key, Column(Order=1), DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Text { get; set; } // Possibly other properties here public virtual Post Post { get; set; } [Key, Column(Order=2)] public virtual int PostId { get; set; } } public class TestContext : DbContext { public DbSet<Post> Posts { get; set; } } 

When a Tag is removed from the Post tag collection, the Entity Framework will issue a DELETE for the tag as indicated here (# 2): http://www.kianryan.co.uk/2013/03/orphaned-child/

Similarly, adding a tag to a message will automatically issue an INSERT and establish an FK relationship.

One note: make sure you use virtual ! I think that was the root of many of my disappointments.

+6
source share
2 answers

Try also to determine the relation on the part of Tag , indicating that each Tag refers to one Post and is required.

Add the required navigation property to Post in Tag :

 public class Tag { // you need an ID public int Id { get; set; } public string Text { get; set; } [Required] public virtual Post Post { get; set; } } 

Alternatively, if you really do not want to add a navigation property, you can use the Fluent API:

 modelBuilder.Entity<Post>().HasMany( p => p.Tags ).WithRequired(); 
+2
source

This is probably necromancy of threads, but I have no comments just to comment. Wouldn't you do what you need?

 public class Tag { [Key, Column(Order=1), DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Text { get; set; } // Possibly other properties here public int PostId { get; set; } [ForeignKey("PostId")] public virtual Post Post { get; set; } } 

PostId is loaded from the database and then used as a foreign key (via annotation) in the Post class. The message is virtual, nothing more. Perhaps you could just go with the main [Key] annotation.

0
source

All Articles