其他分享
首页 > 其他分享> > cry-DRY实体框架搜索调用

cry-DRY实体框架搜索调用

作者:互联网

我有一个称为Entities的实体框架(v5.0)DbContext,该框架由该框架自动生成(我认为我的设计模式是Database First).

我在整个应用程序中都调用了此搜索命令(如下面的代码片段所示).我想干燥我的控制器代码,并将其重构为方法调用.

using (var db = new Entities())
{
    DateTime now = DateTime.Today;
    var activeEvents = db.Events.Where(
        b => !b.removed &&
        b.start_date <= now &&
        b.end_date >= now
    );
}

重构后的示例.

using (var db = new Entities())
{
    var activeEvents = db.Events.GetActive();
    // Or maybe it looks like db.GetActiveEvents();
    // I assume this is dictated by best practice
}

如何实现这一目标?什么是最佳做法?

解决方法:

我可能会采用服务方式;您使用三个主要组件来构建站点:

>表示层
这是MVC网站(但可以是移动网站和应用程序,无论如何)
>服务层
这处理了Presenation层和Data层之间的调用,应用了业务逻辑或可能需要的任何其他校验和(并使其远离表示层)
>数据层
您的实体在这里驻留,并且数据库的上下文也是如此.

为了简单起见,您可以将其保留在一个项目中,但是如果它成为一个大型应用程序,则可能需要将其重构为单独的库.

现在,关于现在如何重构您的情况,我们在其中添加了服务层.我喜欢使用接口,以便以后进行测试时可以很容易地进行测试,可以在进行单元测试时实现“虚拟” IWhateverService,但是在运行实际应用程序时保留当前的实现.然后,您实现接口以与数据接口并返回所需的内容(或执行任何必要的操作[CRUD]).例如

public interface IEventService
{
    IEnumerable<Event> GetActive();
}

public class EventService : IEventService
{
    private readonly Entities entities;
    public EventService(Entities entities)
    {
        this.entities = entities;
    }
    public IEnumerable<Event> GetActive()
    {
        DateTime now = DateTime.Today;
        return this.entities.Events
            .Where(x => !x.removed)
            .Where(x => x.start_date <= now && x.end_date >= now)
            .AsEnumerable();
    }
}

现在我们有了服务,我们可以将其遍历到控制器:

public class EventsController : Controller
{
    private readonly IEventService eventService;

    public EventsService()
    {
        this.eventsService = new EventsService(new Entities());
    }

    // action that gets and views the active events
    public ActionResult Active()
    {
        var activeEvents = this.eventsService.Getactive();
        return View(activeEvents);
    }
}

随着项目的发展,您可以使用CRUD操作更新IEventService(如我之前提到的):

public interface IEventService
{
    IEnumerable<Event> All { get; }

    void AddOrUpdateEvent(Event event);
    IEnumerable<Event> GetActive();
    void RemoveEvent(Event event);
}

当然,将其遍历到EventService,然后最终在EventsController中具有该访问权限.

要进一步执行[几个]步骤,您可以查看Dependency Injection,在其中您指定(一次)如何构建IEventsService,然后在需要时将其作为参数传递给控制器​​的构造函数(如下所示):

public OtherController : Controller
{
    private readonly IUserService;
    private IEventService eventService;

    public OtherController(IUserService userService, IEventService eventService)
    {
        this.userService = userService;
        this.eventService = eventService;
    }

    /* actions */
}

然后,您可以使用诸如Castle Windsor,ninject或其他任何涉及到这些接口的单个​​映射的解决方案,然后(神奇地)将它们提供给控制器的构造函数以供使用.举个例子,这里是Castlewindsor的配置:

container.Register(
    Component.For<IEventService>().ImplementedBy<EventService>()
        .LifestyleSingleton()
);

从本质上说,每次我需要IEventService都提供EventService.

标签:asp-net-mvc-4,entity-framework-5,c
来源: https://codeday.me/bug/20191123/2064068.html