我现在在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/

10-10 13:01