c# - 从类内部访问 DbContext
问题描述
在 Controller 中,我们可以这样做将 DbContext 注入到 Controller 中。这工作正常。
public class HockeyPlayer : Controller
{
private readonly MyDbContext _context;
public HockeyPlayer(MyDbContext context)
{
_context = context;
}
}
然而; 我从未做过的一件事是在类文件中注入(或访问)DbContext。
例如,假设我有一个名为 HockeyPlayerData 的类。
public class HockeyPlayerData
{
private readonly MyDbContext _context;
public HockeyPlayerData(MyDbContext context)
{
_context = context;
}
}
当我尝试使用 _context(对象引用未设置为对象的实例)时,这会引发错误。
var db_query = _context.Set<HockeyPlayer>().FromSqlRaw("execute dbo.GetHockeyPlayer {0}, {1}", 0,
userid).ToList();
我可以让它工作的唯一方法是将 DbContext 传递给类或每个方法。例如:
HockeyPlayerData hp = new HockeyPlayerData(_context);
hp.GetPlayerData();
或者
HockeyPlayerData hp = new HockeyPlayerData();
hp.GetPlayerData(_context);
我真的不喜欢这样,但我也不确定它是否一定是错误的。似乎每个类都应该能够像控制器一样轻松访问数据库。我已经阅读了很多关于此的内容,但我还没有真正得到任何地方。是否有捷径可寻?
你们中的一些人想要更多的代码。这有帮助吗?我的意思是,基本上就是这样。你可以看到我正在尝试在顶部进行注射。但是,当我运行应用程序时,当我尝试在 _dbcontext.Set 中使用数据(对象引用未设置为对象的实例)填充模型(曲棍球运动员)时出现错误。
public class HockeyPlayerData
{
public static MyDbContext _dbcontext;
public HockeyPlayerData(MyDbContext db)
{
_dbcontext = db;
}
public string GetHockeyPlayerData(string userid)
{
string firstname = "";
var query = _dbcontext.Set<HockeyPlayer>().FromSqlRaw("execute
dbo.GetHockeyPlayer {0}, {1}", 0, Convert.ToInt32(userid)).ToList();
for (int i = 0; i < query.Count; i++)
{
firstname = query[i].FirstName;
}
return firstname;
}
}
解决方案
您应该使用依赖注入来解析您的类,而不是使用运算符创建实例new
。下面是一个使用ServiceProvider进行依赖注入的示例:
public class HockeyPlayerData : IHockeyPlayerData
{
private readonly MyDbContext _context;
public HockeyPlayerData(MyDbContext context)
{
_context = context;
}
}
var provider = ServiceCollection()
.AddTransient<IHockeyPlayerData, HockeyPlayerData >()
.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString))
.BuildServiceProvider();
var hockeyPlayerData = provider.GetService<IHockeyProviderData>();
我建议阅读Dependency Inversion Principal。此外,从您使用 Entity Framework(FromSQLRaw
用于检索数据)的方式来看,我认为您可能会受益于阅读 Entity Framework 的入门教程。
如果您的MyDbContext
班级有一个 DBSet,例如:
class MyDbContext
{
public DbSet<PlayerData> PlayerData { get; set; }
}
您可以使用 EF 进行查询,而不是生成原始 SQL。例如:
var data = await context.PlayerData.Where(p => p.PlayerDataID == id).ToListAsync();
推荐阅读
- azure - Azure 数据工厂:如何在复制或导入期间重命名 blob 存储中的 blob csv 或文本文件?
- internet-explorer-11 - 在 IE 11 中下载之前看不到任何禁用自动提示的选项
- ansible - Ansible 变量默认为其他可能未定义的变量
- android - 仅针对 Nexus 5X 获得相同的错误“膨胀类 TextView”
- java - 使用 Opentracing 的 Microprofile 响应式消息传递
- python - 如何通过不覆盖现有数据将数据框写入excel,特别是现有工作表
- c++ - Python Ctypes:OSError:异常:访问冲突读取
- google-app-engine - 为什么我无法访问 VM 上的 Google Cloud Dev App Server(端口 8080)
- javascript - 我只想在单列中显示角度材料表中的单个对象数据
- highcharts - 如何使用 Highmaps 与国家和湖泊一起使用多层地图?