首页 > 解决方案 > 从类内部访问 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;
    }
}

标签: c#entity-framework.net-coredbcontext

解决方案


您应该使用依赖注入来解析您的类,而不是使用运算符创建实例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();

推荐阅读