【问题标题】:entity framework inserting again an existing, referenced entity实体框架再次插入现有的引用实体
【发布时间】:2015-01-08 00:35:31
【问题描述】:

我并不是我的代码有什么问题。

我尝试使用现有实体 (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);

执行后,检查数据库后,我得到下面的图像。

我仍然想知道为什么它保存了一个新位置。 当我调试我的应用程序时,它不会在创建用户时调用 Location save 方法。

我的配置可能有什么问题吗? 谢谢大家。

位置表:

用户表使用了错误的位置:

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    它给你重复,因为你设置了错误的字段。您应该将LocationID 本身设置为您要使用的Location 记录的ID,而不是导航属性。 EF 这样做是因为它更关注 ID,而不是导航属性上的 ID。当它看到对象上存在Location 记录,但看到LocationID 为0 时,它假定用户打算创建一个全新的Location,因此会将一个新的Location 放入数据库中。

    这听起来很荒谬,我知道,但这对你来说是 EF。

    我写了一篇关于此的博客文章,其中包含有关同一问题的更多信息here。

    【讨论】:

    • 好的。脑洞大开。谢谢:')
    • 所以 NavProperty 将始终为空?如果我稍后在代码中访问它,它将只是 null 或者它将包含 id 等于您在 NavPropertyId 中设置的实体?
    • EF 应该为您恢复并填充 NavProperty。应该。
    • 我不确定这是默认行为是否正确。以下行实际上没有指定您描述的行为吗? context.Entry(entity).State = entity.LocationId == 0 ? EntityState.Added : EntityState.Modified; 编辑:对不起没关系,我读错了代码。
    猜你喜欢
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多