gpt4 book ai didi

C# .Net Core 利用 DbSet.FromSql 在基本 Controller 类中利用通用属性

转载 作者:行者123 更新时间:2023-11-30 21:33:44 25 4
gpt4 key购买 nike

我们有一组 Controller 返回 JSON 数据以通过 Web API 同步实体。每个数据实体都有自己的 Controller 和数据模型(“Order, Item, Customer, ...”)所以,这基本上让每个 Controller 都使用完全相同的代码。唯一的区别是 Controller /web api 路径的名称,以及将通过 JSON 返回的数据模型。我们想要做的是拥有一个所有其他 Controller 实现/扩展的基本 Controller (BaseController.cs)。为此,我们希望在每个子 Controller 类定义的基类中有一个虚拟的“EntityType”或“EntityName”属性。然后,我们返回数据的代码不必在每个 Controller 中重复。我们的问题是我们不知道如何存储/传递/定义“类型”或“TEntity”变量。我们需要它来执行“获取”api 方法的主要部分:

例子:

var returnValue = dbContext.Set<GetEntityModelClass()>().FromSql("EXEC dbo.[AJ_P_{0}_API]", GetEntityModelName()).ToList();

我们像这样在 BaseController.cs 类中实现 GetEntityModelName():

public virtual string GetEntityName() { return null; }

子 Controller 类的示例如下:

public override string GetEntityName() { return "Product"; }

我们如何为可以传递 dbContext.Set() 调用所需的值的类似 GetEntityModelClass() 执行此操作?

如果有帮助,这里是我们代码的更大示例:

BaseController.cs
-----------------------------------------
namespace API.Controllers
{
[Produces("application/json")]
public class BaseController : Controller
{

// Returns the name of an entity as it is used in stored procedures, class names, etc...
public virtual string GetEntityName()
{
return null;
}
// Return a type that can be utilized with the dbContext.Set<???>() call
public virtual ??? GetEntityName()
{
return ???;
}
// SiteContext is the API site's data context.
protected readonly SiteContext dbContext;
public BaseController(SiteContext context)
{
dbContext = context;
}

[HttpGet("{token}")]
public IActionResult Get([FromRoute] string token)
{
return Get(token);
}
public IActionResult Results(string token)
{
if (!ModelState.IsValid) { return BadRequest(ModelState); }

var returnValue = dbContext.Set<???GetEntityModel()???>().FromSql("EXEC dbo.[AJ_P_{0}_API] @Token={1}", GetEntityName(), token).ToList();

return Ok(returnValue);
}
}
}

ProductController.cs
-----------------------------------------

namespace API.Controllers
{
[Produces("application/json")]
[Route("/Product")]
public class ProductController : BaseController
{
public override string GetEntityName() {
return "Product";
}
public override ???? GetEntityModel() {
return ( ??? ProductModel type ??? )
}

public ProductController(SiteContext context) : base(context) { }

}
}

最佳答案

我不是通用基础 Controller 的粉丝。但是,您可以使 Controller 通用,将所需的实体类型作为类型参数。那应该可以解决您的问题。

使用你的示例 Controller

[Produces("application/json")]
public abstract class BaseController<TEntity, TModel> : Controller
where TEntity : class
where TModel : class {

// Returns the name of an entity as it is used in stored procedures, class names, etc...
protected virtual string GetEntityName() {
return typeof(TEntity).Name;
}

// SiteContext is the API site's data context.
protected readonly SiteContext dbContext;
protected BaseController(SiteContext context) {
dbContext = context;
}

[HttpGet("{token}")]
public IActionResult Get([FromRoute] string token) {
return GetInternal(token);
}

protected abstract TModel Map(TEntity entity);

protected virtual IActionResult GetInternal(string token)
if (!ModelState.IsValid) { return BadRequest(ModelState); }
var sql = string.Format("EXEC dbo.[AJ_P_{0}_API] @Token", GetEntityName());
var entities = dbContext.Set<TEntity>().FromSql(sql, token).ToList();
var returnValue = entities.Select(Map);
return Ok(returnValue);
}
}

派生 Controller 将简单地提供类型参数。

[Produces("application/json")]
[Route("[controller]")]
public class ProductController : BaseController<Product, ProductModel> {

public ProductController(SiteContext context) : base(context) { }

protected override ProductModel Map(Product entity) {
return new ProductModel {
Property1 = entity.Property1,
//...
PropertyN = entity.PropertyN,
}
}
}

关于C# .Net Core 利用 DbSet<TEntity>.FromSql 在基本 Controller 类中利用通用属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51089747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com