【发布时间】:2020-08-21 10:55:04
【问题描述】:
项目 A 和项目 B 都是 ASP NET Core 2.2 应用程序。
项目 B 将 Hangfire 用于后台作业,并且几乎没有做其他事情,而且它使用 Hangfire 的事实甚至可能并不重要(更多内容在底部)。项目 A 在 B 的 Hangfire 上排队工作。
现在,假设我的班级代表一个任务,称为 Job。这包含在项目 C 中,这是一个由项目 B 引用的普通旧类库,它又引用包含它正在使用的实体的其他项目。
依赖将通过构造函数注入到这个类中:
public class Job
{
public Job(UserManager<ApplicationUser> userManager,
IThisRepository thisRepository,
IThatRepository thatRepository)
{
}
public void Execute(string userId)
{
// this is where the work gets done
}
}
并且在大多数情况下,它们确实被注入:IThisRepository 和 IThatRepository 被注入并且它们工作......大部分时间。
在项目 B 的 Startup.cs(应该运行此作业的那个)中,我手动并成功注册了这些接口,以及它们需要其他一些东西的 DbContext。
UserManager 手动注册相当困难,因为它的构造函数需要所有参数,所以由于我在工作中真的需要它,所以我决定进行一些更改。
现在,我正在使用的实体示例如下:
public class Category
{
[Key]
public int Id { get; set; }
// several other properties of primitive types
public ApplicationUser User { get; set; }
[Required]
public string UserId { get; set; }
}
public class Dish
{
[Key]
public int Id { get; set; }
// several other properties of primitive types
public ApplicationUser User { get; set; }
[Required]
public string UserId { get; set; }
public Category Category { get; set; }
[Required]
public string CategoryId { get; set; }
}
现在的问题是:在 Job 内部,我尝试创建一个新 Dish 并将其与用户和类别相关联。由于我只有用户 ID,而我无权访问 UserManager,这就是我尝试做的事情:
// ...
var category = await categoryRepository.FindByUserAndCode(userId, "ABC");
// this is a category that is guaranteed to exist
var dish = new Dish();
dish.UserId = userId;
// notice there's no dish.User assignment, because I don't have an ApplicationUser object
dish.Category = category;
dishRepository.Upsert(dish); (which internally either creates a new entity or updates the existing one as appropriate)
这就是一切都崩溃的地方,因为它说我试图插入的具有相同 ID 的类别已经存在,所以我试图复制一个主键。
由于该用户的代码为 ABC 的类别存在于数据库中,我认为这很奇怪。
事情是这样的:存储库返回的Category 实例确实填充了UserId 属性,但User 属性是null。
我认为这是导致我的问题的原因:EF 可能看到该属性是 null 并认为该对象是一个新对象。
我不知道为什么会出现null(甚至对于其他所有具有引用用户的属性的实体也会出现),但我试图回溯,而不是只使用用户 ID,我想要尝试让 Hangfire 实例化 Job 并将 UserManager<ApplicationUser> 注入其中,因此至少我可以通过其 id 获取我的用户实例。
值得注意的是,这适用于项目 A 的其他部分,只是当我执行后台作业时出现了可怕的错误,我终生无法弄清楚它是什么。
但是UserManager 的依赖关系很多,我担心我可能会找错树或做错了。
我说我使用 Hangfire 的事实可能并不重要,因为它运行的假设是:只要给我你的类的名称,我会负责实例化它只要 em> 所有的依赖都注册好了。
有没有人做过这件事,可以帮忙解释一下吗?
【问题讨论】:
标签: c# entity-framework-core asp.net-core-2.2 hangfire