我现在在ASP.NET应用程序中(使用 Entity Framework )利用MVC模式的方式如下:
1)我的Models
文件夹包含所有EF实体以及我的ViewModels
2)我有一个Helpers
文件夹,用于存储为特定应用程序目的而创建的类。
3)在我的Helpers
文件夹中,有一个名为MyHelper
的静态类,该类包含使用EF访问数据库的方法。
namespace myApp.Helpers
{
public static class MyHelper
{
public static async Task<ProductVM> GetProductAsync(int productId)
{
using (var context = new myEntities())
{
return await context.vwxProducts.Where(x => x.ProductId == productId).Select(x => new ProductVM { A = x.A, B = x.B }).FirstOrDefaultAsync();
}
}
}
}
4)然后,我的 Controller 在必要时调用以下功能:
namespace myApp.Controllers
{
public class ProductController : Controller
{
[HttpGet]
public async Task<ActionResult> Index(int productId)
{
var productVM = await MyHelper.GetProductAsync(productId);
return View(productVM);
}
}
}
我通常会在SO中遇到类型为“不要使用静态类,静态类是邪恶的,等等”的注释。在这种情况下会适用吗?如果是,为什么?我的应用程序是否应遵循更好的“结构”,以获取最佳实践并避免此类陷阱?
最佳答案
您不能为此真正使用静态类。您的 Entity Framework 上下文每个请求应只有一个实例。您的方法在这里为每种方法实例化一个新的上下文,这将导致Entity Framework出现大量问题。
一般概念很好,但是您的MyHelper
类应该是普通类。添加一个接受上下文实例的构造函数,然后使用DI容器将上下文注入(inject)到helper类中,并将helper类注入(inject)到 Controller 中。
更新
helper
namespace myApp.Helpers
{
public class MyHelper
{
private readonly DbContext context;
public MyHelper(DbContext context)
{
this.context = context;
}
public async Task<ProductVM> GetProductAsync(int productId)
{
return await context.vwxProducts.Where(x => x.ProductId == productId).Select(x => new ProductVM { A = x.A, B = x.B }).FirstOrDefaultAsync();
}
}
}
Controller
namespace myApp.Controllers
{
public class ProductController : Controller
{
private readonly MyHelper myHelper;
public ProductController(MyHelper myHelper)
{
this.myHelper = myHelper;
}
[HttpGet]
public async Task<ActionResult> Index(int productId)
{
var productVM = await myHelper.GetProductAsync(productId);
return View(productVM);
}
}
}
然后,您只需要设置一个DI容器即可注入(inject)所有内容。相应的代码完全取决于最终使用哪个容器,因此我无法真正为您提供进一步的帮助。不过,这通常很简单。只需阅读容器的文档即可。您需要将对象的生存期范围设置为请求。同样,对于不同的容器,它也有所不同,但是它们都具有某种请求范围。
关于c# - 用于数据库访问的静态类的ASP.NET MVC指南,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35367127/