实体框架和MVC:从实体

时间:2017-09-15 23:26:55

标签: c# asp.net-mvc entity-framework json.net odata

我正在分配使用MVC通过OData公开SQL数据。 我正在使用现有项目Visual Studio 2015。 一堆表已经曝光。

首先请接受我的道歉,或许是一篇制作精良的帖子。 我很难搞清楚我实际上在做什么。 另外,我只有一天时间熟悉这个项目。

我知道我说MVC但据我所知,这个项目没有VIEWS。但我确实相信这个项目的消费者会阅读JSON。

我已经使用实体框架为完成我的作业所需的其他表格构建了模型。

我现在正在使用CONTROLLER代码,我想使用工具尽可能地自动化该部分。下面是一个已经定义的CONTROLLER的例子。我将其包含在内,以帮助您了解我正在寻找的工具类型。

这样的工具是否存在?或者我是否必须为我已添加到项目中的表记下一个CONTROLLER?

感谢您阅读我的帖子以及您可以提供的任何帮助:)

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);
    }
}

1 个答案:

答案 0 :(得分:0)

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

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>()

然后,对于您不需要做太多的每个实体,以下是“块”实体控制器的外观:

public class BlockController : BaseController<Block> { }

对于删除和更新,您需要某种方法通过Id(T)标识int key的通用对象。我知道有两种方法可以做到这一点:

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

[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获取对象。您必须为每个实体实现此方法,这比为每个实体编写单独的控制器要少。删除方法与上面的方法几乎相同,只有:var found = GetById(key);

我使用Delete作为示例,但如果您有某种方式通过ID获取实体,则可以非常轻松地实现Post,也可以实现Get(int key)

使用这个通用基类,每个实体的代码很小,为每个实体编写代码不应该太多。