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