我有一个实体ApplicationUser
,其中有一个ICollection
另一个实体Brand
。在我的单元测试中,我向Brand
添加了ICollection
,我调用了SaveChanges()
,但没有任何内容写入我的联结表。
以下是一些代码:
ApplicationUser:
public class ApplicationUser : IdentityUser
{
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[DataType(DataType.Text)]
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[DataType(DataType.Text)]
public string LastName { get; set; }
public virtual ICollection<Brand> Brands { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
这是品牌
public class Brand
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<ApplicationUser> Users { get; set; }
public Brand()
{
Products = new List<Product>();
Users = new List<ApplicationUser>();
}
}
这是我的联结表的映射
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>()
.HasMany(b => b.Brands)
.WithMany(n => n.Users)
.Map(m =>
{
m.MapLeftKey("AspNetUsers.Id");
m.MapRightKey("Brand.Id");
m.ToTable("UserToBrand");
});
}
这是我尝试将更改写入db
的地方public void UpdateUserInformation(ApplicationUser user)
{
using(ApplicationDbContext db = new ApplicationDbContext())
{
db.Database.Log = Console.WriteLine;
db.Users.Attach(user);
db.Entry(user).State = System.Data.Entity.EntityState.Modified;
foreach(Brand b in user.Brands)
{
db.Brands.Attach(b);
db.Entry(b).State = System.Data.Entity.EntityState.Modified;
}
db.SaveChanges();
}
}
输出数据库日志后,我可以看到AspNetUser表和Brand表的更新SQL,但UserToBrand表没有。
答案 0 :(得分:3)
使用断开连接的对象时,需要手动管理同步,包括关系状态。
您需要先从上下文中获取对象,以使所有内容保持同步。
var userDb = db.Users.Find(user.Id);
// Updates scalar properties.
db.Entry(userDb).CurrentValues.SetValues(user);
foreach(Brand b in user.Brands)
{
// Is still required to prevent EF adds new brand.
db.Entry(b).State = EntityState.Modified;
userDb.Brands.Add(b);
}
db.SaveChanges();
或者,如果您确实想要使用断开连接的对象,则需要手动创建关系。
db.Entry(user).State = EntityState.Modified;
foreach(Brand b in user.Brands)
{
db.Entry(b).State = System.Data.Entity.EntityState.Modified;
(IObjectContextAdapter)db).ObjectContext.ObjectStateManager
.ChangeRelationshipState(user, b, u => u.Brands, EntityState.Added);
}
db.SaveChanges();
顺便说一下,Attach
方法是多余的,因为它与将状态更改为EntityState.Unchanged
相同,然后在附加后再将其更改为EntityState.Modified
。
更多