ASP.NET MVC,实体框架:通过动作实现的与通用模型无关的控制器类

时间:2014-07-15 10:12:57

标签: c# asp.net-mvc entity-framework asp.net-mvc-4 ef-database-first

我试图实施这种机制:

模型具有位字段:is_active,因此我使用它来切换主窗体上的可见性。控制器中的动作如下:

public ActionResult Toggle(int id)
    {
        Country country = _db.Countries.Find(id);
        country.is_active = country.is_active == null ? true : !country.is_active;
        _db.SaveChanges();
        return RedirectToAction("Index");
    }

我希望我的管理查找控制器从该泛型类派生,并使用它的实现来执行常见操作,如切换。

我已经创建了ActionResult Toggle(int id)的ITogglable接口,所以我在特定的控制器(CountryController : Controller, ITogglable)中实现它,但我必须每次都实现它。相反,我更喜欢我的CountryController,RegionController等派生自通用类(即Togglable),这些类已经实现了这样的方法:

public virtual ActionResult Toggle(int id)
{
    CurrentModelTypeUsedInController lookup = _db.CurrentModelTypeUsedInController.Find(id);
    lookup .is_active = lookup .is_active == null ? true : !lookup.is_active;
    _db.SaveChanges();
    return RedirectToAction("Index");
}

这甚至可能吗?我不知道如何使它与查询无关,所以我不必每次都提供CurrentModelTypeUsedInController的类型。

1 个答案:

答案 0 :(得分:3)

您需要一些抽象来实现这一目标。

首先,您需要一个定义is_active的抽象,例如

public interface IActive 
{ 
    bool is_active { get; set; } 
}

所有类型如CountryCurrentModelTypeUsedInController都需要实现此抽象

public class Country : IActive 
{
    public bool is_active { get; set; }
}

有了这个,我们定义了通用控制器。这里的关键点是放置在泛型IActive)上的泛型约束TModelType)。通过定义所有类型的TModelType必须实现IActive,代码知道该类型保证公开名为is_active的属性

public class AbstractController<TModelType> : Controller 
    where TModelType : class, IActive
{
    private readonly DbContext _db;

    public AbstractController()
    {
        _db = new DbContext("connection");
    }

    public ActionResult Toggle(int id)
    {
        TModelType instance = _db.Set<TModelType>().Find(id);
        instance.is_active = instance.is_active == null ? true : !instance.is_active;
        _db.SaveChanges();
        return RedirectToAction("Index");
    }
}

每个控制器都可以从AbstractController<>

派生
public sealed class CountryController : AbstractController<Country>
{
}