I am new to ASP.NET Core / C#, and trying to learn. I have read tutorials, watched videos, and even bought a book. I wanted to inject my AppDBcontext to my models..
Here is my Startup class
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
string dbConnection = Configuration["ConnectionStrings:AzureSQL"];
services.AddDbContext<AppDbContext>(options => {
options.UseSqlServer(dbConnection);
});
services.AddScoped<AppDbContext>();
services.AddMvc();
}
and my AppDbContext.cs
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
public DbSet<Monthly> Monthly { get; set; }
public DbSet<Bill> Bill { get; set; }
}
I tried something like from my models
public class Bill
{
public AppDbContext _ctx;
public Bill(AppDbContext db)
{
_ctx = db;
}
public class BillGetParams
{
public string MonthlyID { get; set; }
public string UserID { get; set; }
public string BillID { get; set; }
}
public int ID { get; set; }
public int? MonthlyID { get; set; }
public string BillName { get; set; }
public string Comment { get; set; }
public int? Amount { get; set; }
public bool? Payed { get; set; }
public bool? Recursive { get; set; }
public string UserID { get; set; }
public string UUID { get; set; }
public DateTime? CreatedAt { get; set; }
public static async Task<List<Bill>> LoadBills(BillGetParams billParams)
{
var bills = _ctx.Bill.FromSql($@"
SELECT * FROM bills WHERE MonthlyId={billParams.MonthlyID}");
return await bills.ToListAsync();
}
public static async Task<Bill> LoadBill(BillGetParams param)
{
var bill = _ctx.Bill.FromSql($@"
SELECT * FROM bills
WHERE UserID='{param.UserID}' AND ID='{param.BillID}'
");
return await bill.SingleOrDefaultAsync();
}
edit: added partial code for Bill Class and to methods that use _ctx, also update the constructor by removing static and private->public;
I get an error:
System.NullReferenceException: Object reference not set to an instance of an object.
because it seemed like the assignment of db to _ctx never happened..
I'm not sure which is best, but I use my AppDbContext before like this. Should I continue using it like this?
using(var ctx = new AppDbContext())
{
var bills = ctx.Bill.FromSql($@"select 1 from bills")
// do stuff
}
From the internet examples, DI worked fine from controllers.. but I don't want to do SQL stuff from controllers.. is there a better way to abstract SQL / data access in dotnet? Or I am doing it wrong?
solution1: so after reading, tryouts, solutions from @Bharat, and experiments. I solved my problem, in simplest way.. hopefully I am right. I added this in my BillController that use Bill.LoadBill() I can access my sql well now.
private Bill _bill;
public BillController(AppDbContext db)
{
_bill = new Bill(db);
}
Thank you!
privateaccess modifier on your constructor method topublic Bill (...), I would also question why you have itstaticinprivate static AppDbContext _ctx;?private static AppDbContextis because my editorvs codekeep complaining to meAn object reference is required for the non-static field, method, or property 'Bill._ctx'Billclass ? as i don't see any where. Because this will give you a instance ofAppDbContext()Billclass? I'm sure I've added it toAppDbContext.csBill.LoadBill()methods from some where to get data from sql. so there you need to do likeBill yourInstanceName = new Bill(new AppDbContext())this will provide context to your_ctxusing constructure.