Sto usando Entity Framework 7 RC1 e ho le entità:
public class Post {
public Int32 Id { get; set; }
public String Title { get; set; }
public virtual IList<PostTag> PostsTags { get; set; }
}
public class Tag {
public Int32 Id { get; set; }
public String Name { get; set; }
public virtual IList<PostTag> PostsTags { get; set; }
}
public class PostTag {
public Int32 PostId { get; set; }
public Int32 TagId { get; set; }
public virtual Post Post { get; set; }
public virtual Tag Tag { get; set; }
}
La configurazione del modello per queste entità è la seguente:
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
builder.Entity<Post>(b => {
b.ToTable("Posts");
b.HasKey(x => x.Id);
b.Property(x => x.Id).UseSqlServerIdentityColumn();
b.Property(x => x.Title).IsRequired().HasMaxLength(100);
});
builder.Entity<Tag>(b => {
b.ToTable("Tags");
b.HasKey(x => x.Id);
b.Property(x => x.Id).UseSqlServerIdentityColumn();
b.Property(x => x.Name).IsRequired().HasMaxLength(100);
});
builder.Entity<PostTag>(b => {
b.ToTable("PostsTags");
b.HasKey(x => new { x.PostId, x.TagId });
b.HasOne(x => x.Post).WithMany(x => x.PostsTags).HasForeignKey(x => x.PostId);
b.HasOne(x => x.Tag).WithMany(x => x.PostsTags).HasForeignKey(x => x.TagId);
});
}
Ho creato la migrazione e il database. Poi ho provato a creare un post:
Context context = new Context();
Post post = new Post {
PostsTags = new List<PostTag> {
new PostTag {
Tag = new Tag { Name = "Tag name" }
}
},
Title = "Post title"
};
context.Posts.Add(post);
await _context.SaveChangesAsync();
E su Salva ricevo il seguente errore:
An error occurred while updating the entries.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_PostTag_Tag_TagId".
The conflict occurred in database "TestDb", table "dbo.Tags", column 'Id'.
The statement has been terminated.
Qualcuno conosce il motivo di questo errore?
Ho avuto gli stessi problemi. Ecco la soluzione che ho trovato. Questa domanda SO mi ha aiutato molto.
Prima di tutto, aggiungi un public DbSet<Tag> Tags {get; set;}
alla tua classe Context
se manca.
Quindi modifica la creazione del post come segue
Context context = new Context();
var tmpTag = new Tag { Name = "Tag name" } //add the tag to the context
context.Tags.Add(tmpTag);
Post post = new Post {
PostsTags = new List<PostTag>(), // initialize the PostTag list
Title = "Post title"
};
context.Posts.Add(post);
var postTag = new PostTag() {Post = post, Tag = tag}; // explicitly initialize the PostTag AFTER addig both Post and Tag to context
post.PostTags.Add(postTag); // add PostTag to Post
await _context.SaveChangesAsync();
Aggiungendo esplicitamente post
e tag
a context.Posts
e context.Tags
prima di tentare di creare l'oggetto PostTag
consente a EF di gestire correttamente gli ID durante la scrittura nel DB sottostante.
Per completezza, dopo aver risolto questa parte della gestione delle relazioni molti-a-molti, sono attualmente alle prese con CascadeDelete Entity Framework Core (EF7), ma questa è una storia diversa.