Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
82 views
in Technique[技术] by (71.8m points)

c# - Access DbContext from Inside of a Class

In a Controller, we can do this to inject the DbContext in to the Controller. This works fine.

public class HockeyPlayer : Controller
{
    private readonly MyDbContext _context;

    public HockeyPlayer(MyDbContext context)
    {
        _context = context;
    }
}

However; one thing I have never been able to do is to inject (or access) DbContext in a class file.

For example, say I have a class named HockeyPlayerData.

public class HockeyPlayerData
{
    private readonly MyDbContext _context;

    public HockeyPlayerData(MyDbContext context)
    {
        _context = context;
    }
}

This throws an error when I try to use _context (Object reference not set to an instance of the object).

var db_query = _context.Set<HockeyPlayer>().FromSqlRaw("execute dbo.GetHockeyPlayer {0}, {1}", 0, 
userid).ToList();

The only way I can get it to work is to pass in DbContext to the class or each method. For example:

HockeyPlayerData hp = new HockeyPlayerData(_context);
hp.GetPlayerData();

Or

HockeyPlayerData hp = new HockeyPlayerData();
hp.GetPlayerData(_context);

I really don't like that but I am also not sure if it is necessarily wrong. Seems each class should be able to easily access the database like the controllers do. I have read quite a bit about this but I haven't really gotten anywhere. Is there an easy way to do this?

Some of you wanted more code. Does this help? I mean this is basically it. You can see I am trying to do injection at the top. But when I run the application I get an error when I try to fill the model (Hockey Player) with data (Object reference not set to instance of the object) at _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;
    }
}
question from:https://stackoverflow.com/questions/65851329/access-dbcontext-from-inside-of-a-class

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should resolve your class using dependency injection rather than creating an instance using the new operator. Here is an example that uses a ServiceProvider for dependency injection:

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>();

I would suggest reading up on the Dependency Inversion Principal. Also, from the way you are using Entity Framework (using FromSQLRaw to retreive data), I think you may benefit for reading Entity Framework's Getting Started Tutorial.

If your MyDbContext class has a DBSet like:

class MyDbContext
{
    public DbSet<PlayerData> PlayerData { get; set; }
}

You can use EF to do the query rather than generating raw SQL. For example:

var data = await context.PlayerData.Where(p => p.PlayerDataID == id).ToListAsync();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...