我的代码真的不怎么样。
我尝试使用现有实体(Location)
并将其用作另一个实体(ApplicationUser)
的属性之一。
我希望ApplicationUser
引用现有的Location
,但它会创建一个新的Location
并引用它。
以下是实体:
public class ApplicationUser : IdentityUser
{
public int? LocationId { get; set; }
public Location Location { get; set; }
}
public class Location
{
public Location()
{
this.Users = new HashSet<ApplicationUser>();
}
public int LocationId { get; set; }
public string Country { get; set; }
public string Province { get; set; }
public string Area { get; set; }
public virtual ICollection<ApplicationUser> Users { get; set; }
}
以下是我的配置:
public class ApplicationUserConfiguration : EntityTypeConfiguration<ApplicationUser>
{
public ApplicationUserConfiguration()
{
this.HasOptional(i => i.Location)
.WithMany(i => i.Users)
.HasForeignKey(i => i.LocationId);
}
}
public class LocationConfiguration : EntityTypeConfiguration<Location>
{
public LocationConfiguration()
{
this.HasKey(i => i.LocationId);
this.Property(i => i.Country).HasMaxLength(100);
this.Property(i => i.Province).HasMaxLength(100);
this.Property(i => i.Area).HasMaxLength(100);
}
}
以下是我保存位置的方法:
public Task SaveAsync(IUnitOfWork unitOfWork, Location entity)
{
var context = (ApplicationDbContext)unitOfWork.Context;
context.Entry(entity).State = entity.LocationId == 0
? EntityState.Added
: EntityState.Modified;
return context.SaveChangesAsync();
}
在我的代码中,我首先预先填充位置。 然后我将现有位置称为用户的位置。
//successfully called an existing location. LocationId is 5
var adminLocation = await this._locationService.FindByArea("Philippines", "Laguna", "Calamba");
admin = new ApplicationUser
{
LockoutEnabled = false,
Email = Settings.Default.DefaultAdminEmail,
UserName = Settings.Default.DefaultAdminUserName,
FirstName = "admin",
LastName = "yow",
// used here
Location = adminLocation
};
// save user
var identityResult = await this._userService.RegisterUserAsync(admin,
Settings.Default.DefaultAdminPassword);
执行后,检查数据库后,我会得到以下图片。
我仍然想知道为什么它保存了一个新位置。 当我调试我的应用程序时,它在创建用户时不会调用位置保存方法。
我的配置可能有什么问题吗? 谢谢你们。
位置表:
用户表使用错误的位置:
答案 0 :(得分:1)
它会给你重复,因为你设置了错误的字段。您应该使用要使用的LocationID
记录的ID设置Location
本身,而不是导航属性。 EF这样做是因为它更注重ID,而不是导航属性上的ID。当它看到对象上存在Location
条记录,但看到LocationID
为0时,它会假定用户打算创建一个全新的Location
,从而会创建一个新的{{1}}一进入数据库。
这听起来很荒谬,我知道,但这对你来说是EF。
我写了一篇关于这篇文章的博文,其中有关于同一问题的更多信息here。