简体   繁体   English

实体框架再次插入现有的引用实体

[英]entity framework inserting again an existing, referenced entity

I'm not really what is wrong with my code. 我不是我的代码有什么问题。

I try to use an existing entity (Location) and use it as one of the properties of another entity (ApplicationUser) . 我尝试使用现有实体(Location)并将其用作另一个实体(ApplicationUser)的属性之一。

I expect the ApplicationUser to reference the existing Location but it, instead, creates a new Location and reference this instead. 我希望ApplicationUser引用现有的Location但是它会创建一个新的Location并引用它。

Here are the entities: 以下是实体:

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; }
}

Here are my configurations: 这是我的配置:

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);
    }
}

Here is how I save locations: 这是我保存位置的方法:

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();
}

On my code, I pre-populate first the locations. 在我的代码中,我首先预填充了位置。 And then I call an existing location to be used as the location of a user. 然后,我将现有位置称为用户位置。

//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);

After execution, upon checking the database, I get images below. 执行后,检查数据库后,我得到下面的图像。

I'm still wondering why it saved a new Location. 我仍然想知道为什么它保存了一个新位置。 When I debug my application, it does not call the Location save method when creating the user. 当我调试应用程序时,在创建用户时它不会调用Location保存方法。

Is there anything wrong with my configuration perhaps? 我的配置可能有问题吗? Thanks guys. 多谢你们。

Location Table: 位置表:

在此处输入图片说明

User Table using the wrong Location: 用户表使用错误的位置:

在此处输入图片说明

It's giving you duplicates because you're setting the wrong field. 它给您重复的内容,因为您设置了错误的字段。 You should be setting the LocationID itself with the ID of the Location record you want to use, not the navigational property. 您应该使用您要使用的Location记录的ID(而不是导航属性)设置LocationID本身。 EF does this because it pays more attention to the ID, rather than the ID on the navigational property. EF之所以这样做,是因为它更加关注ID,而不是导航属性上的ID。 When it sees a Location record present on the object, but sees that the LocationID is 0 it assumes that the user is intending to create a brand new Location , and will thus put a new one into the database. 当它看到对象上存在一个Location记录,但看到LocationID为0时,则假定用户打算创建一个全新的Location ,因此会将一个新的Location放入数据库中。

It sounds ridiculous, I know, but that's EF for you. 我知道这听起来很荒谬,但这对您来说是EF。

I wrote a blog post about that with more information on this same issue here . 我在此处撰写了一篇有关该主题的博客文章,其中提供了有关同一问题的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM