将DbContext添加到所有类,而不仅仅是.NET Core中的控制器

Fer*_*jal 1 c# entity-framework dbcontext .net-core asp.net-core

我想将我当前的DbContext添加到我使用的任何类中,目前我只是像传统变量一样传递_context.

在这个控制器示例中,每次我想创建一个Item时,我都会传递_context

[HttpPost("receta/{id}")]
[APIauth("medico")]
public IActionResult PostItemsReceta(int id, [FromBody]Data[] items) {
    var tran = _context.Database.BeginTransaction(); //DBB transaction begins
    try {
        foreach (Data item in items)
            new Item(id, item, _context); //I pass the _context like this.

        tran.Commit();
        return Ok();

    } catch (Exception e) {
        tran.Rollback();
        return BadRequest("Not inserted!!");
    }            
}
Run Code Online (Sandbox Code Playgroud)

在课程项目中,我有这个

public class Item
{
    [Key]
    public int id { get; set; }
    public DateTime? fcaducidad { get; set; }
    public string nombre { get; set; }
    public Int32 diagnostico { get; set; }

    public Item() { }

    public Item (int receta, Data i, MyDbContext _context) {
        try {
            var q = $"EXEC ItemReceta_Insert @idItemFarmacia={i.itemFarmacia.id}" +
            $", @idDiagnostico={i.diagnostico}, @cantidad={i.cantidad}" +
            $", @receta={receta}, @posologia='{i.posologia}'";

            _context.Database.ExecuteSqlCommand(q); 
        } catch (Exception e) {
            throw new Exception("Error al insertar ItemReceta", e);
        }            
    }

    public static Item[] Report( int receta, MyDbContext _context) 
    {
        string q = $"EXEC Item_Report @receta={receta}";
        return _context.Item.FromSql(q).ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不想只是直接访问控制器中的上下文,因为我想要多次使用它

new Item(id, item);
Run Code Online (Sandbox Code Playgroud)

new Item(id, item, _context);
Item.Report(bla, _context);
new WhatEverClass(name, age, _context);
Run Code Online (Sandbox Code Playgroud)

Kei*_*las 6

我认为你并没有真正分开你的担忧,有很多方法可以解决这个问题,但是我会提出一个非常简单的方法来将事情注入你自己的类中(我会在你的解决方案中省略一些属性)把事情简单化 ).您需要做的主要事情是将您的课程注册为服务.所以..

首先,让你的物品成为POCO

 public class Item
    {
        public int Id { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

现在将您的代码与您尝试将项目放入和放出数据库的方式相关联,使构造函数获取您的DbContext以便它将被注入

public class ItemService 
{
    private readonly ApplicationContext _context;

    public ItemService(ApplicationContext context)
    {
        _context = context;
    }

    public void Add(Item item)
    {
        // A paramatized query of some sort to prevent sql injection
        // see https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/advanced
        var parameters = new List<object>();
        _context.Database.ExecuteSqlCommand("", parameters);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您配置服务的地方添加您的项目服务

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationContext>();
            services.AddScoped<ItemService>();         
        }
Run Code Online (Sandbox Code Playgroud)

现在在你的控制器构造函数中说你想要这个服务,

private readonly ItemService _itemService
public MyFancyPantsController(ItemService itemService)
{
  _itemService = itemService;
}
Run Code Online (Sandbox Code Playgroud)

现在在您的帖子上,您可以访问该服务

 [Route("post")]
    [HttpPost()]        
    public IActionResult PostItem()
    {
        // construct / deserialize items, then add them...
        _itemService.Add(new Item());
        return Ok();
    }
Run Code Online (Sandbox Code Playgroud)

现在....你可能会发现你有很多实体(比如Item)并且为它们创建服务都是PITA,所以你可能想要更通用的Repository服务.