在我们的Web.API项目中,我们使用实体框架6.我们有一个DataModel类,它包含DatabaseContext。 DataModel是一个[ThreadStatic]
Singleton。模型类中的EF上下文
像这样:
public class DataModel
{
[ThreadStatic] private static DataModel _instance;
public static DataModel Instance => _instance ?? (_instance = new DataModel());
public DatabaseContext Context { get; private set; }
private DataModel()
{
Context = NewContext();
}
}
现在,在我们的(部分)模型类之一,我们使用的情况下是这样的:
public partial class Job
{
public User CreatedByUser
{
get { return DataModel.Instance.Context.Users.FirstOrDefault(d => d.Username == CreatedBy); }
}
}
我们在另一个数据库中的表对应的用户搜索。这是有效的,但在我看来,这不是一个美丽的解决方案。特别是如果我们计划将我们的项目迁移到.NET Core并对数据库上下文使用依赖注入。
我的问题是,有没有一种模式,它解决了更优雅的问题?依赖注入在这里不起作用,因为实体框架生成模型对象。或者,如果我们将这些代码从部分类移动到例如一个util类?但是我们怎么能在那里注入上下文呢?
实体类中的单例上下文和上下文都是反模式。所以首先尝试摆脱这些模式,而不用担心DI。之后你会看到,将代码转换为DI会更容易。 *如何做到这一点,很大程度上取决于你的架构的其他部分,以便对其进行任何明智的说明。 –
这个datamodel驻留在什么层?它是从API返回的模型还是尝试在数据库抽象层?通常我会建议使用存储库模式,但这并不适合所有问题。让模型通过数据库调用(“活动记录模式”)填充自己通常会导致比解决问题更多的问题。 – CodeCaster
使用正确的外键可以解决问题。作业是通过UserId *上的CreatedBy用户*关联的,而不是用户名(除非用户名是用户表中的PK,在这种情况下,您应该重新考虑这一点)。在EF中映射该关系,然后如果实体已连接,则可以使用延迟加载导航到“CreatedByUser”,或者在查询中使用“包含”子句立即检索它。您当前的解决方案不是线程安全的,特别是考虑到您有一个具有多个线程的asp.net应用程序(至少1x同时请求)。 – Igor