【问题标题】:POCO Relationship Updates with Entity Framework Core 2POCO 与 Entity Framework Core 2 的关系更新
【发布时间】:2018-11-24 09:35:42
【问题描述】:

我的EntityFrameworkCore 2.0 解决方案中有一个模型。类布局如下;

public class Trader : AuditableEntity
{
    public string Name { get; set; }
    public string Telephone { get; set; }
    public string Email { get; set; }
    /*REMOVED FOR BREVITY*/


    public ApplicationUser AccountManager { get; set; }
}

ApplicationUser 在哪里实现IdentityUser

public class ApplicationUser : IdentityUser<int>, IEntity

现在我希望能够定期更新AccountManager,因为交易员会定期通过。

为此,我有以下服务方法(为简洁起见);

var trader = context.Find<Trader>(traderId);

var user = await userContext.FindByIdAsync(userId.ToString());

trader.User = user;

context.Save(trader, userName);

如果我尝试这样做,我会得到错误;

System.Data.SqlClient.SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“AspNetUsers”中插入标识列的显式值。

这意味着它正在尝试将新用户插入用户表。现在上面的用户已经存在。据我所知,如果将有效的 Id 传递给实体,实体框架只会创建关系?如果发送过来的复杂对象有一个空值的子实体会插入一个新的?

我可以添加一个额外的字段;

public int UserId { get; set; }

并将其设置为类中 ApplicationUser 的 FK,但我希望将类保持最小?这是可能的还是这是设置它的唯一方法? (或者我可以使用流利的配置进行设置吗?

【问题讨论】:

    标签: c# asp.net-identity entity-framework-core


    【解决方案1】:

    您正在使用不同的上下文。

    每个上下文都不会跟踪所有两个实体:

    • trader 实例被context 实例跟踪。
    • user 实例(如果被 userContext 实例跟踪)。

    所以因为您在context.Save(trader, userName); 中使用context,所以以下选项之一:

    • 使用该上下文检索traderinstance
    • 在更新User 属性之前使用context.Attach(trader)
    • 最好在Trader 类上添加外键属性UserId,并将该属性值设置为trader.UserId = user.Id

    【讨论】:

    • 啊,好吧,正确我使用的是UserManager&lt;ApplicationUser&gt;,所以EF不会看到Trader.AccountManager.Id != null并自动将其状态设置为被引用而不是插入一个新实例(即.Attach不假定为默认值)?
    • 是的。而已。 EF 只查看EntityState 枚举(AddedModified 等)。因此,如果您向其添加一个新实体,即使它具有 Id != null,状态仍将是 EntityState.Added
    猜你喜欢
    • 1970-01-01
    • 2018-04-01
    • 2011-01-06
    • 1970-01-01
    • 2022-08-02
    • 2017-11-04
    • 2018-03-08
    • 1970-01-01
    • 2017-02-11
    相关资源
    最近更新 更多