EF Core 多对一:添加新元素会删除所有其他条目
EF Core Many-To-One: Adding new Element deletes all other Entries
我有一个简单的多对一关系:
public class Company
{
public IEnumerable<User> Users { get; set; }
public int Id { get; set; }
}
public class User
{
public int CompanyId { get; set; }
[Required]
public Company Company { get; set; }
public int Id { get; set; }
}
我还尝试将我的用户定义如下(但没有成功):
public class User
{
[Required]
[ForeignKey("Company")]
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public int Id { get; set; }
}
我有以下方法向公司添加新用户:
public async Task<bool> Add(User user)
{
try
{
await this.context.Set<User>().AddAsync(user);
await this.context.SaveChangesAsync();
return true;
}
catch (Exception)
{
return false;
}
}
我这样调用这个方法:
var company = await this.companyService.Get(1); // this works
if (company == null)
{
return;
}
await this.userService.Add(
new User
{
CompanyId = company.Id,
Company = company, // I also tried to remove this line - no effect
});
我的 DbContext 看起来像这样:
public class AppContext : IdentityDbContext
{
public AppContext(DbContextOptions<AppContext> options)
: base(options)
{
}
public DbSet<Company> Company { get; set; }
public DbSet<User> User { get; set; }
}
既然我已经解释了场景,那么问题来了。当我将用户添加到公司时,所有条目都被删除。 “删除”是什么意思?整个 table “用户”是空的,没有任何条目。在我添加用户并检查 company
之前,我可以看到所有用户。如果我在插入后再次获取公司,属性 Users
returns 一个空列表(不为空)。这也会影响值的删除和更新。我已经在这里解决这个问题 3 天了,完全不知道我做错了什么。
试试这个类(如果使用 ef core 5+,可以省略数据注释)
public class User
{
[Key]
public int Id { get; set; }
[Required]
public int? CompanyId { get; set; }
[ForeignKey(nameof(CompanyId ))]
[InverseProperty("Users")]
public virtual Company Company { get; set; }
}
public class Company
{
[Key]
public int Id { get; set; }
[InverseProperty(nameof(User.Company))]
public virtual ICollection<User> Users { get; set; }
}
和代码
var company = await this.companyService.Get(1);
await this.userService.Add(new User { CompanyId = company.Id});
public async Task<bool> Add(User user)
{
try
{
context.Set<User>().Add(user);
await context.SaveChangesAsync();
return true;
}
catch (Exception)
{
return false;
}
}
经过30个小时的调试,我发现了问题。它与 EF 无关(我在某种程度上预料到了,因为我确实复制并粘贴了整个文档 5 次)。
也许有人有类似的问题,所以我 post 在这里回答,但请注意,这对我的用例来说是高度特定的。
我将当前登录的用户存储在 ProtectedSessionStorage 中,如下所示:
await this.protectedSessionStorage.SetAsync("user", await this.userService.Get(id));
无论出于何种原因(我又搜索了 2 小时),我的一些属性被忽略并且未正确存储(即 属性 Company.Users
),即使我没有使用解释此行为的任何注释。当我再次加载这个确切的用户时,由于其他一些未知原因,EF 认为(因为缺少 Company.Users
属性)公司没有任何用户。同样,文档中没有描述这种行为,而且我发现没有人遇到这个特定问题,所以我可能做了一些描述这种行为的事情。
解决方案:取Json.NET from Newtonsoft,将其序列化,然后将序列化后的字符串存储在受保护的会话存储中。我真的只是改变了这一点,一切都按预期进行。当然,当我访问存储时,我必须反序列化所有内容。
await this.protectedSessionStorage.SetAsync("user", JsonConvert.SerializeObject(await this.userService.Get(id)));
我有一个简单的多对一关系:
public class Company
{
public IEnumerable<User> Users { get; set; }
public int Id { get; set; }
}
public class User
{
public int CompanyId { get; set; }
[Required]
public Company Company { get; set; }
public int Id { get; set; }
}
我还尝试将我的用户定义如下(但没有成功):
public class User
{
[Required]
[ForeignKey("Company")]
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public int Id { get; set; }
}
我有以下方法向公司添加新用户:
public async Task<bool> Add(User user)
{
try
{
await this.context.Set<User>().AddAsync(user);
await this.context.SaveChangesAsync();
return true;
}
catch (Exception)
{
return false;
}
}
我这样调用这个方法:
var company = await this.companyService.Get(1); // this works
if (company == null)
{
return;
}
await this.userService.Add(
new User
{
CompanyId = company.Id,
Company = company, // I also tried to remove this line - no effect
});
我的 DbContext 看起来像这样:
public class AppContext : IdentityDbContext
{
public AppContext(DbContextOptions<AppContext> options)
: base(options)
{
}
public DbSet<Company> Company { get; set; }
public DbSet<User> User { get; set; }
}
既然我已经解释了场景,那么问题来了。当我将用户添加到公司时,所有条目都被删除。 “删除”是什么意思?整个 table “用户”是空的,没有任何条目。在我添加用户并检查 company
之前,我可以看到所有用户。如果我在插入后再次获取公司,属性 Users
returns 一个空列表(不为空)。这也会影响值的删除和更新。我已经在这里解决这个问题 3 天了,完全不知道我做错了什么。
试试这个类(如果使用 ef core 5+,可以省略数据注释)
public class User
{
[Key]
public int Id { get; set; }
[Required]
public int? CompanyId { get; set; }
[ForeignKey(nameof(CompanyId ))]
[InverseProperty("Users")]
public virtual Company Company { get; set; }
}
public class Company
{
[Key]
public int Id { get; set; }
[InverseProperty(nameof(User.Company))]
public virtual ICollection<User> Users { get; set; }
}
和代码
var company = await this.companyService.Get(1);
await this.userService.Add(new User { CompanyId = company.Id});
public async Task<bool> Add(User user)
{
try
{
context.Set<User>().Add(user);
await context.SaveChangesAsync();
return true;
}
catch (Exception)
{
return false;
}
}
经过30个小时的调试,我发现了问题。它与 EF 无关(我在某种程度上预料到了,因为我确实复制并粘贴了整个文档 5 次)。
也许有人有类似的问题,所以我 post 在这里回答,但请注意,这对我的用例来说是高度特定的。
我将当前登录的用户存储在 ProtectedSessionStorage 中,如下所示:
await this.protectedSessionStorage.SetAsync("user", await this.userService.Get(id));
无论出于何种原因(我又搜索了 2 小时),我的一些属性被忽略并且未正确存储(即 属性 Company.Users
),即使我没有使用解释此行为的任何注释。当我再次加载这个确切的用户时,由于其他一些未知原因,EF 认为(因为缺少 Company.Users
属性)公司没有任何用户。同样,文档中没有描述这种行为,而且我发现没有人遇到这个特定问题,所以我可能做了一些描述这种行为的事情。
解决方案:取Json.NET from Newtonsoft,将其序列化,然后将序列化后的字符串存储在受保护的会话存储中。我真的只是改变了这一点,一切都按预期进行。当然,当我访问存储时,我必须反序列化所有内容。
await this.protectedSessionStorage.SetAsync("user", JsonConvert.SerializeObject(await this.userService.Get(id)));