Eager many to many projection not working - entity-framework

My classes:
public class Post : Entity
{
public bool Active { get; set; }
public IList<Comment> Comments { get; set; }
public IList<Category> Categories { get; set; }
public Post ()
{
Categories = new List<Category>();
Comments = new List<Comment>();
}
}
public class Comment: Entity
{
public string UserName { get; set; }
public CommentStatus Status { get; set; }
public int PostId { get; set; }
public Post Post { get; set; }
}
public class Category: Entity
{
public string Name { get; set; }
public IList<Post> Posts { get; set; }
public Category()
{
Posts= new List<Post>();
}
}
My mapping:
public class PostMap: EntityTypeConfiguration<Post>
{
public PostMap()
{
ToTable("Posts");
HasKey(x => x.Id)
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(x => x.Categories)
.WithMany(x => x.Posts)
.Map(x =>
{
x.MapLeftKey("PostId");
x.MapRightKey("CategoryId");
x.ToTable("PostXCategory");
});
HasMany(x => x.Comments)
.WithRequired(x => x.Post)
.HasForeignKey(x => x.PostId);
}
}
public class CategoryMap: EntityTypeConfiguration<Category>
{
public CategoryMap()
{
ToTable("Categories");
HasKey(x => x.Id)
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
and finally my projection:
var query = _sqlRepository.Query<Post>()
.Where(x => x.Active)
.Select(x => new
{
Post = x,
Categories = x.Categories.ToList(),
Comments = x.Comments.Where(c => c.Status == CommentStatus .Approved).ToList()
});
var data = query.ToList();
The problem is that eager loading is not working for "Categories", just for "Comments".
When I check my projection (var data), I see this:
But when I select "Post" (data.Select(x => x.Post)) the Categories is empty:
Why Categories is empty and comments not?

Related

Entity Framework 6 several one-to-mmay

Onother problem with Entity Framework 6. I don't know why, but I have some trouble to get back my object frome the database when I queue 2 one-to-many relationships.
My plain objects
public class Plan
{
public int id { get; set; }
public int largeur { get; set; }
public int longueur { get; set; }
public string nom { get; set; }
public virtual List<Etage> listEtages { get; set; }
public Plan() { }
}
public class Etage
{
public int id { get; set; }
public virtual List<PositionModule> listPositionModule { get; set; }
public virtual Plan plan { get; set; }
public Etage() { }
}
public class PositionModule
{
public int id { get; set; }
public int x1 { get; set; }
public int x2 { get; set; }
public int y1 { get; set; }
public int y2 { get; set; }
public string lineId { get; set; }
public virtual Module module { get; set; }
public virtual Etage etage { get; set; }
public PositionModule() { }
}
public class Module
{
public int id { get; set; }
public string libe { get; set; }
public string coupePrincipe { get; set; }
public virtual TModule typeModule { get; set; }
public decimal prix { get; set; }
public Module()
{
}
}
Ef6 fluent mapping
public class PlanConfiguration : EntityTypeConfiguration<Plan>
{
public PlanConfiguration()
{
ToTable("Plan");
HasKey<int>(a => a.id);
Property<int>(a => a.largeur).IsRequired();
Property<int>(a => a.longueur).IsRequired();
Property(a => a.nom).HasColumnType("varchar").HasMaxLength(50);
}
}
public class EtageConfiguration : EntityTypeConfiguration<Etage>
{
public EtageConfiguration()
{
ToTable("Etage");
HasKey<int>(a => a.id);
HasRequired<Plan>(x => x.plan).WithMany(x => x.listEtages);
}
}
public class PositionModuleConfiguration : EntityTypeConfiguration<PositionModule>
{
public PositionModuleConfiguration()
{
ToTable("PositionModule");
HasKey<int>(a => a.id);
HasRequired<Module>(a => a.module);
HasRequired<Etage>(x => x.etage).WithMany(x => x.listPositionModule);
Property<int>(x => x.x1);
Property<int>(x => x.x2);
Property<int>(x => x.y1);
Property<int>(x => x.y2);
Property(a => a.lineId).HasColumnType("varchar").HasMaxLength(30);
}
}
public class ModuleConfiguration : EntityTypeConfiguration<Module>
{
public ModuleConfiguration()
{
ToTable("Module");
HasKey<int>(a => a.id);
HasOptional<TModule>(a => a.typeModule);
Property(a => a.libe).HasColumnType("varchar").HasMaxLength(150);
Property(a => a.coupePrincipe).HasColumnType("varchar");
}
}
At the moment I'm able to store a Plan which has a list of Etage with many PositionModule.
But when I want to get back my all plan with a get by id, the listEtages is empty.
By checking on the database, all foreign keys are good and I use the one-to-many with two other (simplier) objects and it works fine...
It's my first project with EF6 so if you have any tips to share, it will be a pleasure.
Thanks
Update
My DTOs
public class PlanDTO
{
public int id { get; set; }
public int largeur { get; set; }
public int longueur { get; set; }
public string nom { get; set; }
public List<EtageDTO> lesEtages { get; set; }
public PlanDTO()
{
lesEtages = new List<EtageDTO>();
}
}
public class EtageDTO
{
public int id { get; set; }
public List<PositionModuleDTO> lesModules { get; set; }
public PlanDTO plan { get; set; }
public EtageDTO()
{
lesModules = new List<PositionModuleDTO>();
plan = new PlanDTO();
}
}
public class PositionModuleDTO
{
public int id { get; set; }
public int x1 { get; set; }
public int x2 { get; set; }
public int y1 { get; set; }
public int y2 { get; set; }
public string lineId { get; set; }
public ModuleDTO module { get; set; }
public EtageDTO etage { get; set; }
public PositionModuleDTO()
{
module = new ModuleDTO();
}
}
public class ModuleDTO
{
public string libe { get; set; }
public int id { get; set; }
public string coupePrincipe { get; set; }
public TModule typeModule { get; set; }
}
How I mapp my DTOs and Plain objects (with automapper)
--- ViewModelToDomain ---
CreateMap<PlanDTO, Plan>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.largeur, map => map.MapFrom(vm => vm.largeur))
.ForMember(g => g.longueur, map => map.MapFrom(vm => vm.longueur))
.ForMember(g => g.nom, map => map.MapFrom(vm => vm.nom))
.ForMember(g => g.listEtages, map => map.MapFrom(vm => vm.lesEtages));
CreateMap<EtageDTO, Etage>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.listPositionModule, map => map.MapFrom(vm => vm.lesModules))
.ForMember(g => g.plan, map => map.MapFrom(vm => vm.plan));
CreateMap<PositionModuleDTO, PositionModule>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.x1, map => map.MapFrom(vm => vm.x1))
.ForMember(g => g.x2, map => map.MapFrom(vm => vm.x2))
.ForMember(g => g.y1, map => map.MapFrom(vm => vm.y1))
.ForMember(g => g.y2, map => map.MapFrom(vm => vm.y2))
.ForMember(g => g.module, map => map.MapFrom(vm => vm.module))
.ForMember(g => g.etage, map => map.MapFrom(vm => vm.etage));
CreateMap<ModuleDTO, Module>()
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.libe, map => map.MapFrom(vm => vm.libe))
.ForMember(g => g.typeModule, map => map.MapFrom(vm => vm.typeModule))
.ForMember(g => g.coupePrincipe, map => map.MapFrom(vm => vm.coupePrincipe));
--- DomainToViewModel ---
CreateMap<Plan, PlanDTO>();
CreateMap<Etage, EtageDTO>();
CreateMap<PositionModule, PositionModuleDTO>();
CreateMap<Module, ModuleDTO>();
The controller where I create and try to get back my plan
[HttpPost]
public ActionResult SavePlan(PlanDTO plan)
{
if (plan != null)
{
Plan planP = new Plan();
plan.nom = "test";
planP=Mapper.Map<PlanDTO, Plan>(plan);
try
{
_planService.Create(planP);//The plan is create
/*
refers to
public virtual void Insert(T entity)
{
dbSet.Add(entity);
}
*/
_planService.Save();
}
catch(Exception e)
{
throw (e);
}
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
}
[HttpPost]
public JsonResult GetPlan(int id)
{
try
{
List<ModuleDTO> lesModules = Mapper.Map<List<Module>, List<ModuleDTO>>(_moduleService.DonneTous().ToList());
PlanDTO plan = Mapper.Map<Plan, PlanDTO>(_planService.Get(id));//I have id, largeur, longueure and nom but listEtages is empty (all data are in database)
/*
refers to
public virtual T GetById(int id)
{
return dbSet.Find(id);
}
*/
return Json(plan);
}
catch(Exception e)
{
return Json("An Error Has occoured");
}
}

The Entity create an additional table for many to-many relationships

Today I got a question about how to create a many to many mapping using Entity Framework Code First fluent api.
The problem is that the entity create an additional table beyond that was set for me.
public class Person
{
public Person()
{
courses = new HashSet<Course>();
}
public int PersonID { get; set; }
public String Name { get; set; }
public ICollection<Course> courses { get; set; }
}
public class Course
{
public Course()
{
people = new HashSet<Person>();
}
public int CourseID { get; set; }
public String Name { get; set; }
public ICollection<Person> people { get; set; }
}
public class PersonCourse
{
public int fk_CourseID { get; set; }
public virtual Course course { get; set; }
public int fk_PersonID { get; set; }
public virtual Person person { get; set; }
public String AnotherInformation { get; set; }
}
public class PersonDataConfiguration : EntityTypeConfiguration<Person>
{
public PersonDataConfiguration()
{
ToTable("Person");
Property(c => c.Name).IsRequired();
this.HasMany(c => c.courses).WithMany(t => t.people).Map(m => { m.MapLeftKey("CourseID"); m.MapRightKey("PersonID"); });
}
}
public class CourseDataConfiguration : EntityTypeConfiguration<Course>
{
public CourseDataConfiguration()
{
ToTable("Course");
Property(c => c.Name).IsRequired();
this.HasMany(c => c.people).WithMany(t => t.courses).Map(m => { m.MapLeftKey("PersonID"); m.MapRightKey("CourseID"); });
}
}
public class PersonCourseDataConfiguration : EntityTypeConfiguration<PersonCourse>
{
public PersonCourseDataConfiguration()
{
ToTable("PersonCourseX");
HasKey(c => new { c.fk_CourseID, c.fk_PersonID });
Property(c => c.AnotherInformation).IsRequired();
this.HasRequired(c => c.person).WithMany().HasForeignKey(t => t.fk_PersonID);
this.HasRequired(c => c.course).WithMany().HasForeignKey(t => t.fk_CourseID);
}
}
public class ProgramTesteContext : DbContext
{
public ProgramTesteContext()
: base("MyConnectionString")
{
}
public DbSet<Person> Person { get; set; }
public DbSet<Course> Course { get; set; }
public DbSet<PersonCourse> PersonCourse { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Properties<String>()
.Configure(p => p.HasColumnType("varchar"));
modelBuilder.Properties<String>()
.Configure(p => p.HasMaxLength(100));
modelBuilder.Configurations.Add(new PersonDataConfiguration());
modelBuilder.Configurations.Add(new CourseDataConfiguration());
modelBuilder.Configurations.Add(new PersonCourseDataConfiguration());
}
}
The entity set up two tables for mapping:
PersonCourseX created by me and another CoursePerson table containing only foreign keys without anotherinformation field.
How to make this second table is not created?
Change PersonCourseDataConfiguration as follows:
public class PersonCourseDataConfiguration : EntityTypeConfiguration<PersonCourse>
{
public PersonCourseDataConfiguration()
{
ToTable("PersonCourseX");
HasKey(c => new { c.fk_CourseID, c.fk_PersonID });
Property(c => c.AnotherInformation).IsRequired();
this.HasRequired(c => c.person).WithMany(c => c.courses).HasForeignKey(t => t.fk_PersonID);
this.HasRequired(c => c.course).WithMany(c => c.people).HasForeignKey(t => t.fk_CourseID);
}
}
Remove the commented lines:
public class PersonDataConfiguration : EntityTypeConfiguration<Person>
{
public PersonDataConfiguration()
{
ToTable("Person");
Property(c => c.Name).IsRequired();
//this.HasMany(c => c.courses).WithMany(t => t.people).Map(m => { m.MapLeftKey("CourseID"); m.MapRightKey("PersonID"); });
}
}
public class CourseDataConfiguration : EntityTypeConfiguration<Course>
{
public CourseDataConfiguration()
{
ToTable("Course");
Property(c => c.Name).IsRequired();
//this.HasMany(c => c.people).WithMany(t => t.courses).Map(m => { m.MapLeftKey("PersonID"); m.MapRightKey("CourseID"); });
}
}
Change Person and Course as follows:
public class Person
{
//.. other properties
public ICollection<PersonCourse> courses { get; set; }
}
public class Course
{
//.. other properties
public ICollection<PersonCourse> people { get; set; }
}

Entity Framework 6: Add to child collections

I am using EF6 code first. I have an parent entity (Expense) which has collection of child entity (Tag). Entities are
public class Expense : Entity
{
//public Expense()
//{
// this.Tags = new HashSet<Tag>();
//}
public string Title { get; set; }
public ICollection<Tag> Tags { get; set; }
//public long TagId { get; set; }
public decimal Amount { get; set; }
public long ByUserId { get; set; }
public User ByUser { get; set; }
public long? ForUserId { get; set; }
public User ForUser { get; set; }
public DateTime ExpenseDate { get; set; }
}
public class Tag : Entity
{
public Tag()
{
this.Expenses = new HashSet<Expense>();
}
public string Name { get; set; }
public virtual ICollection<Expense> Expenses { get; set; }
public long OrganizationId { get; set; }
public Organization Organization { get; set; }
}
Configured as
public ExpenseConfiguration()
{
this.HasRequired(x => x.ByUser)
.WithMany()
.HasForeignKey(x => x.ByUserId)
.WillCascadeOnDelete(false);
this.HasOptional(x => x.ForUser)
.WithMany()
.HasForeignKey(x => x.ForUserId)
.WillCascadeOnDelete(false);
this.HasMany(x => x.Tags)
.WithMany(t => t.Expenses)
.Map(et => {
et.MapLeftKey("ExpenseId");
et.MapRightKey("TagId");
et.ToTable("tblExpenseTags");
});
}
public TagConfiguration()
{
this.HasRequired(x => x.Organization)
.WithMany()
.HasForeignKey(p => p.OrganizationId)
.WillCascadeOnDelete(false);
}
The way I am saving entity
var tags = new List<Tag>();
foreach (var item in expense.Tags)
{
var tag = _TagHandler.Get().Where(x => x.Id == item.Id).FirstOrDefault();
tags.Add(tag);
}
entity.Tags.Clear();
foreach (var item in tags)
{
expense.Tags.Add(item);
}
if (expense.Id == 0)
{
entity.CreatedDate = DateTime.UtcNow;
entity.UpdatedDate = DateTime.UtcNow;
updated = EntityRepository.Add(entity);
}
else
{
expense.UpdatedDate = DateTime.UtcNow;
updated = EntityRepository.Update(entity);
}
UnitOfWork.Commit();
When i Create Expense I add multiple tags to it and it save successfully in tblExpenseTags, but the problem is when I add new tags to Expense they are not saving into tblExpenseTags table. I used sql profiler to see what calls are going to SQL database and I don't see any insert call at the time of update expense.
Please let me know what wrong am I doing ?

Missing Information When Eager Loading With Entity Framework

When trying to eager load the PriceGridRow, the index and value properties of PriceGridColumn are populated but the Id and the ProduceGridRowId are not. If i try to explicitly include PriceGridColumns it get duplicate columns (ie. i have 10 columns but the object returned by EF has 20) and half of the the columns returned are fully populated and the other half are not.
I've been pulling what's left of my hair trying to figure out why this is occurring. Can anyone see based on my configuration why it would be acting this way? Thanks!
The code i use to get columns are:
public override PriceGrid GetLoadedById(object id)
{
var priceGrid = Entities
Include(x => x.PriceGridRows.Select(o => o.PriceGridColumns))
.FirstOrDefault(x => x.Id == (int) id);
return priceGrid;
}
Here are the classes in question
public class PriceGrid : DomainEntity<int>
{
public string Description { get; set; }
public Product Product { get; set; }
public int ProductId { get; set; }
public List<PriceGridRow> PriceGridRows
{
get { return _priceGridRow; }
set { _priceGridRow = value; }
}
}
public class PriceGridRow : DomainEntity<int>
{
public PriceGrid PriceGrid { get; set; }
public int PriceGridId { get; set; }
public ProductOption ProductOption { get; set; }
public int ProductOptionId { get; set; }
public List<PriceGridColumn> PriceGridColumns { get; set; }
}
And finally the third level of nesting
public class PriceGridColumn : DomainEntity<int>
{
public PriceGridRow PriceGridRow { get; set; }
public int PriceGridRowId { get; set; }
public int Index { get; set; }
public decimal Value { get; set; }
}
Here are my mapping files
public class PriceGridMap : EntityTypeConfiguration<PriceGrid>
{
public PriceGridMap()
{
HasKey(x => x.Id);
Property(x => x.Description);
HasRequired(x => x.Product);
HasMany(x => x.PriceGridRows)
.WithRequired(x => x.PriceGrid)
.HasForeignKey(x => x.PriceGridId)
.WillCascadeOnDelete();
}
}
public class PriceGridRowMap : EntityTypeConfiguration<PriceGridRow>
{
public PriceGridRowMap()
{
HasKey(x => x.Id);
HasRequired(x => x.ProductOption);
HasMany(x => x.PriceGridColumns)
.WithRequired(x => x.PriceGridRow)
.HasForeignKey(x => x.PriceGridRowId)
.WillCascadeOnDelete();
}
}
public class PriceGridColumnMap : EntityTypeConfiguration<PriceGridColumn>
{
public PriceGridColumnMap()
{
HasKey(x => x.Id);
Property(x => x.Index);
Property(x => x.Value);
HasRequired(x => x.PriceGridRow);
}
}
Try to remove this mapping line from PriceGridColumnMap:
HasRequired(x => x.PriceGridRow);
which basically means that the relationship the PriceGridRow navigation property belongs to does not have an inverse navigation property. It is a shortcut for:
HasRequired(x => x.PriceGridRow)
.WithMany()...
But this is in contradiction with the mapping in PriceGridRowMap:
HasMany(x => x.PriceGridColumns)
.WithRequired(x => x.PriceGridRow)...
which says that the PriceGridRow navigation property does have an inverse navigation property, namely PriceGridColumns.

EF Code First mapping for collection

I'm using EF 4.1 RC Code first. I have a many to many relation working with a composite PK in the junction table Friends. We explicitly need a separate Friends class (don't ask) which represents our junction table. Our goal is to be able to control the delete process from the User entity. Please read this before reading the rest: http://mocella.blogspot.com/2010/01/entity-framework-v4-object-graph.html. So, we managed to create our composite PK but this broke our mapping for the collection. The question is how to map FriendsCol?
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public virtual ICollecion<Friends> FriendsCol { get; set; }
}
public class Friends
{
public int User1Id { get; set; }
public int User2Id { get; set; }
public User User1 { get; set; }
public User User2 { get; set; }
}
Have a composite key mapping
public class FriendsMap : EntityTypeConfiguration<Friends>
{
HasKey(m => new { m.userId1 , m.userId2 });
//this.HasRequired(x => x.User1)
//.WithMany()
//.HasForeignKey(x => x.User1Id)
//.WillCascadeOnDelete(false);
//this.HasRequired(x => x.User2)
// .WithMany()
// .HasForeignKey(x => x.User2Id)
// .WillCascadeOnDelete(false);
}
public class UserMap : EntityTypeConfiguration<UserNew>
{
public UserMap()
{
ToTable("users");
Property(user => user.Name).HasColumnName("name");
// HasMany<Friends>(user => user.FriendsCol).WithMany();
}
}
What about this:
public class FriendsMap : EntityTypeConfiguration<Friends>
{
HasKey(m => new { m.userId1 , m.userId2 });
this.HasRequired(x => x.User1)
.WithMany()
.HasForeignKey(x => x.User1Id)
.WillCascadeOnDelete(false);
this.HasRequired(x => x.User2)
.WithMany(u => u.FriendsCol)
.HasForeignKey(x => x.User2Id)
.WillCascadeOnDelete(false);
}
public class UserMap : EntityTypeConfiguration<UserNew>
{
public UserMap()
{
ToTable("users");
Property(user => user.Name).HasColumnName("name");
}
}
Edit:
I just made very simple example and it works without any problem:
class Program
{
static void Main(string[] args)
{
using (var context = new Context())
{
context.Database.Delete();
context.Database.CreateIfNotExists();
var u1 = new User() { Name = "A" };
var u2 = new User() { Name = "B" };
var u3 = new User() { Name = "C" };
var f1 = new Friends() { User1 = u1, User2 = u2};
var f2 = new Friends() { User1 = u1, User2 = u3 };
context.Friends.Add(f1);
context.Friends.Add(f2);
context.SaveChanges();
}
}
}
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public virtual ICollection<Friends> FriendsCol { get; set; }
}
public class Friends
{
public int User1Id { get; set; }
public int User2Id { get; set; }
public User User1 { get; set; }
public User User2 { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Friends> Friends { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Friends>()
.HasKey(m => new { m.User1Id, m.User2Id });
modelBuilder.Entity<Friends>()
.HasRequired(x => x.User1)
.WithMany()
.HasForeignKey(x => x.User1Id)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Friends>()
.HasRequired(x => x.User2)
.WithMany(u => u.FriendsCol)
.HasForeignKey(x => x.User2Id)
.WillCascadeOnDelete(false);
}
}
Ok, here is what really should happen:
class Program
{
static void Main(string[] args)
{
int id1;
int id2;
using (var context = new Context())
{
context.Database.Delete();
context.Database.CreateIfNotExists();
var u1 = new User() { Name = "A" };
var u2 = new User() { Name = "B" };
var u3 = new User() { Name = "C" };
var f1 = new Friends() { User1 = u1, User2 = u2 };
var f2 = new Friends() { User1 = u1, User2 = u3 };
u1.FriendsCol.Add(f1);
u1.FriendsCol.Add(f2);
context.SaveChanges();
id1 = u1.Id;
id2 = u2.Id;
}
using (var context = new Context())
{
var u1 = context.Users.Find(id1);
var friendsToRemove = u1.FriendsCol.Where(f => f.User2.Id == id2).ToList();
foreach (var friend in friendsToRemove)
{
u1.FriendsCol.Remove(friend);
}
context.SaveChanges();
}
}
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Friends> FriendsCol { get; set; }
public User()
{
FriendsCol = new List<Friends>();
}
}
public class Friends
{
public int User1Id { get; set; }
public int User2Id { get; set; }
public User User1 { get; set; }
public User User2 { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Friends> Friends { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Friends>()
.HasKey(m => new { m.User1Id, m.User2Id });
modelBuilder.Entity<Friends>()
.HasRequired(x => x.User1)
.WithMany()
.HasForeignKey(x => x.User1Id);
modelBuilder.Entity<Friends>()
.HasRequired(x => x.User2)
.WithMany(u => u.FriendsCol)
.HasForeignKey(x => x.User2Id);
}
}
Here is another fail to delete related entities. And this is the error: *A relationship from the 'Order_Lines' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'Order_Lines_Target' must also in the 'Deleted' state.*
class Program
{
static void Main(string[] args)
{
int orderid1;
int Lineid2;
using (var context = new Context())
{
var u1 = new Order() { Name = "A" };
var l1 = new OrderLine() { Name = "L1" };
var l2 = new OrderLine() { Name = "L2" };
u1.Lines.Add(l1);
u1.Lines.Add(l2);
context.Orders.Add(u1);
context.SaveChanges();
Orderid1 = u1.Id;
Lineid2 = l2.Id;
}
using (var context = new Context())
{
var u1 = context.Orders.Find(Orderid1);
foreach (var item in u1.Lines)
{
if (item.Id == Lineid2)
{
u1.Lines.Remove(item);
break;
}
}
context.SaveChanges();
}
}
}
public class OrderLine
{
public int Id { get; set; }
public string Name { get; set; }
public Order Order { get; set; }
}
public class Order
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<OrderLine> Lines { get; set; }
public Order()
{
Lines = new List<OrderLine>();
}
}
public class Context : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<OrderLine> OrderLiness { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().HasMany<OrderLine>(o => o.Lines).WithRequired(l => l.Order);
}
}