[英]Entity Framework Core dependency injection to models
我是ASP.NET Core / C#的新手,正在尝试学习。 我已经阅读了教程,观看了视频,甚至买了一本书。 我想将AppDBcontext
注入模型。
这是我的Startup
班
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();
}
和我的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; }
}
我从模型中尝试过类似的东西
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();
}
编辑:为Bill
类和使用_ctx
方法添加了部分代码,还通过删除static
和private-> public来更新构造函数;
我收到一个错误:
System.NullReferenceException:对象引用未设置为对象的实例。
因为似乎db
分配给_ctx
从未发生过。
我不确定哪个是最好的,但是我像这样之前使用AppDbContext
。 我应该继续这样使用吗?
using(var ctx = new AppDbContext())
{
var bills = ctx.Bill.FromSql($@"select 1 from bills")
// do stuff
}
从Internet的示例中,DI在控制器上运行良好。.但是我不想在控制器上执行SQL工作。.是否有更好的方法在dotnet
抽象SQL /数据访问? 还是我做错了?
solution1:所以在阅读完之后,尝试了一下,尝试了@Bharat的解决方案,并进行了实验。 我用最简单的方法解决了问题。希望我是对的。 我在使用Bill.LoadBill()
BillController
中添加了此BillController
,现在可以很好地访问SQL了。
private Bill _bill;
public BillController(AppDbContext db)
{
_bill = new Bill(db);
}
谢谢!
之所以得到System.NullReferenceException: Object reference not set to an instance of an object.
是因为您的构造方法是private
:
private Bill(AppDbContext db) { _ctx = db; }
解决方案:您的构造函数应为public
。
否则,无法在自己的类之外访问它。 您可以通过在_ctx = db
上放置一个断点来测试它,您将看到它没有被调用。
为了进一步阅读和理解,我建议您阅读此Microsoft文档: ASP.NET Core中的依赖项注入
我看到的最大错误是这个:
public class Bill
{
public AppDbContext _ctx;
public Bill(AppDbContext db)
{
_ctx = db;
}
public static async Task<List<Bill>> LoadBills(BillGetParams billParams)
{
var bill = _ctx... //trying to acces an instance property in static context, does not work. and shouldn't even compile.
}
}
我认为为模型提供直接访问其实例的方法很好,但是即使这样做是为了填充额外的属性或列表,也请不要这样做。
这样,您可以在整个应用程序中拆分我们的DataAccess代码(sql)。 相反,最好将所有dataAcces分组在控制器中,或者甚至在单独的项目中作为服务分组。
服务的优势在于:
这将导致以下代码:
public class EntityFrameworkBillService : IBillService
{
public AppDbContext _ctx;
public Bill(AppDbContext db)
{
_ctx = db;
}
public async Task<List<Bill>> GetBills(BillGetParams billParams)
{
var bill = _ctx... //trying to acces an instance property in static context, does not work. and shouldn't even compile.
}
}
//startup.cs:
services.AddTransient<IBillService,EntityFrameworkBillService>()
//Usage
public MyController(IBillService billService) //constructor
{
var dollahBills = billService.GetBills();
}
//And if you really wish this method to be there, and be lazy (but be warned: its an anti pattern)
public class Bill
{
public static async Task<List<Bill>> GetBills(BillGetParams billParams)
{
//Make sure your ServiceProvider is available as static on Program in startup.cs.
return Program.ServiceProvider.Resolve<IBillService>().GetBills(billParams);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.