asp.net-core - EF Core 3.0 使用 DbSet.Add 方法时反转 SQL 插入语句
问题描述
我最近将我的 .NET Core Web 应用程序从使用 EF Core 2.2 升级到使用 EF Core 3.0。升级后,我遇到了一个奇怪的问题。我想将一个用户插入数据库,为此我必须插入几个不同的表 -
- 用户表
- 用户电子邮件表
- 用户角色表
我首先插入用户表,这样我可以在“UserEmail”和“UserRole”表中使用“UserId”。我为每个表/实体都有一个存储库类——“UserRepository”、“UserRoleRepository”和“UserEmailRepository”。这些存储库类中的每一个都继承自“BaseRepository”。
public RepositoryBase(DbContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
}
public virtual void Add(TEntity entity)
{
_dbSet.Add(entity);
}
*TEntity 是“用户”、“用户角色”或“用户电子邮件”
插入操作在“UserService”中完成,该“UserService”注入包含上述 3 个存储库的“UnitOfWork”类。insert 方法还传入一个“UserDTO”对象,所有需要插入的必要用户信息都位于该对象中。
user = new User
{
FirstName = userDTO.FirstName,
LastName = userDTO.LastName
};
_unitOfWork.UserRepository.Add(user);
_unitOfWork.UserRoleRepository.Add(new UserRole
{
UserId = user.UserId,
RoleId = role.RoleId
});
_unitOfWork.UserEmailRepository.Add(new UserEmail
{
UserId = user.UserId,
EmailAddress = userDTO.EmailAddress,
});
_unitOfWork.Save();
对于插入“UserRole”表,我已经在前一行中获得了 roleId
在我的“UnitOfWork”类的实现中
_unitOfWork.Save()
做了一个。_context.SaveChanges()
我希望所有这些都在同一个事务中,并且我想为“UserRole”和“UserEmail”表使用“UserId”。
所以问题是当代码调用_unitOfWork.Save()
它时会引发与“UserId”相关的 FK 异常。我查看了正在生成的查询,SQL Insert 语句的顺序与我在代码中调用它们的顺序相反,它看起来像这样 -
- “插入用户.电子邮件...”
- “插入用户.角色...”
- “插入用户。用户...”
什么时候应该
- “插入用户。用户...”
- “插入用户.角色...”
- “插入用户.电子邮件...”
由于某种原因,Entity Framework 生成 SQL 语句的顺序与应有的顺序相反,因此“User.Roles”表和“User.Emails”表没有要插入的有效“UserId”。
现在,这只是在我从 EF 2.2 升级到 EF 3.0 之后才开始发生的,之前一切正常。我查看了这是否与任何重大更改有关,但没有看到任何可以提供帮助的东西。
也许我错过了一些我需要的小配置,我只是不确定。有什么我需要添加到 Startup.cs 文件中以使这项工作像以前一样吗?
解决方案
推荐阅读
- r - 为什么 plotly 图表不能一致地在 flexdashboard 中呈现?
- node.js - node worker_threads console.log 在 postMessage 之后
- html - 将背景应用于跨度 - 但不是文本所在的位置
- php - 在php中下载大文件的正确方法
- go - Go 中的 len(string) 和 len(slice)s O(1) 操作吗?
- python - python解析json文件
- javascript - 如何在节点 js 中检查文本框 id 是否为空
- azure-machine-learning-service - 如何从本地部署的 AzureML 容器中公开端口?
- reactjs - 如果它在对象内部,如何更新 redux reducer 中的值
- javascript - React-select {creatable} 与用户输入的条目一起工作,因为只显示没有选项