首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实体框架和MVC:从实体生成控制器代码

实体框架和MVC:从实体生成控制器代码
EN

Stack Overflow用户
提问于 2017-09-16 07:26:55
回答 1查看 109关注 0票数 0

我的任务是通过OData使用MVC公开SQL数据。我正在处理一个现有的项目,Visual Studio 2015。一堆表格已经暴露出来了。

首先,请接受我的道歉,这可能是一篇做工粗糙的帖子。我很难弄清楚我真正在用的是什么。此外,我只有一天的时间来熟悉这个项目。

我知道我说的是MVC,但据我所知,这个项目没有视图。然而,我相信这个项目的消费者会阅读JSON。

我已经使用Entity Framework为完成任务所需的其他表构建了模型。

我现在正在编写控制器代码,我想使用一个工具来尽可能地自动化这一部分。下面是一个已经定义的控制器的例子。我将其包含进来是为了帮助您对我正在寻找的工具类型有所了解。

这样的工具存在吗?或者,我是否必须为添加到项目中的表使用记事本控制器?

感谢您阅读我的帖子,并感谢您能提供的任何帮助:)

代码语言:javascript
复制
public class BlockController : ODataController
{
    AccordNewModel _db = new AccordNewModel();

    [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IHttpActionResult Get()
    {
        return Ok(_db.Block.AsQueryable());
    }

    [ODataRoute()]
    [HttpPost]
    [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IHttpActionResult Post(Block newBlock)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        _db.Block.Add(newBlock);
        _db.SaveChanges();
        return Created(newBlock);
    }

    [ODataRoute()]
    [HttpPut]
    [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IHttpActionResult Put(Block block)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        _db.Block.AddOrUpdate(p => new { p.BlockID }, block);
        _db.SaveChanges();

        return Updated(block);
    }

    [HttpDelete]
    public IHttpActionResult Delete([FromODataUri] int key)
    {
        var block = _db.Block.SingleOrDefault(t => t.BlockID == key);
        _db.Block.Remove(block);
        _db.SaveChanges();

        return Content(HttpStatusCode.NoContent, "Deleted");
    }

    protected override void Dispose(bool disposing)
    {
        _db.Dispose();
        base.Dispose(disposing);
    }
}
EN

回答 1

Stack Overflow用户

发布于 2017-09-26 16:23:57

多次编写非常相似的控制器代码意义不大,我建议不要为每个实体生成一个控制器。相反,您可以使用通用解决方案:

代码语言:javascript
复制
public class BaseController<T> : ODataController
{
    AccordNewModel _db = new AccordNewModel();

    [EnableQuery]
    public IHttpActionResult Get()
    {
        return Ok(_db.Set<T>().AsQueryable());
    }

    [HttpPost]
    public IHttpActionResult Post(T posted)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        var added = _db.Set<T>().Add(posted);
        _db.SaveChanges();
        return Created(added);
    }

    //Etc... Write generic controller methods using Db.Set<T>()

然后,对于每个你不需要做太多的实体,下面是你的“块”实体控制器的样子:

代码语言:javascript
复制
public class BlockController : BaseController<Block> { }

对于delete和update,您需要通过Id (int key)来标识T的通用对象。我知道有两种方法:

1:让实体实现一个接口IHasId,以确保它们具有int Id属性,然后向BaseController类添加一个通用约束,如下所示:public class BaseController<T> : ODataController where T : IHasId。Delete方法可能如下所示:

代码语言:javascript
复制
[HttpDelete]
public IHttpActionResult Delete([FromODataUri] int key)
{
    var found = _db.Set<T>().FirstOrDefault(e => e.Id == key);
    if(found != null)
    {
        _db.Set<T>().Remove(found);
        _db.SaveChanges();
        return StatusCode(System.Net.HttpStatusCode.NoContent);
    }
    else
    {
        return NotFound();
    }
}

或者,2:使BaseController类抽象并添加:protected abstract T GetById(int id);。然后继承类(比如'BlockController')必须实现一个方法来通过id从Db获取对象。你必须为每个实体实现这个方法,这仍然比为每个实体编写单独的控制器要少。delete方法看起来与上面的方法几乎相同,除了:var found = GetById(key);

我使用Delete作为示例,但是如果您有一些方法可以通过id获取实体,那么您可以很容易地实现Post,也可能实现Get(int key)

使用这个通用基类,每个实体的代码是最少的,并且为每个实体编写它不应该是太多的工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46248619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档