干实体框架搜索呼叫 [英] DRY Entity Framework Search Call
问题描述
我有一个实体框架(V5.0)的DbContext
名为实体
这是自动生成的框架(我觉得我的设计模式是数据库优先)。
I have an Entity Framework (v5.0) DbContext
called Entities
that is auto-generated by the framework (I think my design pattern is Database First).
我有我整个应用程序中调用这个搜索命令(在下面的片段所示)。我要干我的控制器code和重新考虑此因素成一个方法调用。
I have this search command (shown in the snippet below) that I am calling throughout the application. I want to DRY up my controller code and re-factor this into a method call.
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
}
一个人怎么会去实现这一目标?什么是最好的做法?
How would one go about achieving this? What is considered best practice?
推荐答案
我可能会采取的服务方式;你有三个主要组成部分建立您的网站:
I would probably take the service approach; You build your site with three main components:
- presentation层结果
这是MVC网站(但可能是一个移动网站和应用程序,等等) - 服务层结果
这个处理presenation层和数据层之间的通话,应用业务逻辑或任何其他校验和可能是必要的(和从presentation层保持它的距离) - 数据层结果
在这里,你的实体
居住和上下文到数据库中。
- Presentation Layer
This is the MVC website (but could be a mobile site, and application, whatever) - Service Layer
this handles the calls between the Presenation layer and the Data layer, applying business logic or whatever other checksums may be necessary (and keeping it away from the presentation layer) - Data Layer
Here yourEntities
reside and the context to the database.
为了简单起见,你可以保持这一个项目,但如果这成为一个大的应用程序,你可能要重构它到分离库。
For the sake of simplicity, you can keep this in one project, but if this becomes a big application you probably want to refactor it out in to separated libraries.
现在,就如何重构你的情况的现在的,我们在里面添加服务层。我喜欢所以它使事情变得简单后来来测试我可以实现一个虚拟使用接口 IWhateverService
当我去的单元测试,但在运行时保持当前实施实际应用。然后你实现与数据接口,并返回你所需要的接口(或执行任何必要行动[CRUD])。例如。
Now, as far as how to refactor your situation now, we add the service layer in there. I like to use interfaces so it makes things easy to test later on I can implement a "dummy" IWhateverService
when I go to unit test, but keep the current implementation when running the actual application. Then you implement the interface to interface with the data and return what you need (or perform whatever actions are necessary [CRUD]). e.g.
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();
}
}
现在,我们有我们的服务,我们可以通过它下探到控制器:
Now that we have our service, we can plumb it through to the controller:
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);
}
}
随着项目的进展,您可以更新 IEventService
与CRUD操作(就像我刚才提到的):
As the project evolves, you can update your IEventService
with CRUD operations (like I mentioned earlier):
public interface IEventService
{
IEnumerable<Event> All { get; }
void AddOrUpdateEvent(Event event);
IEnumerable<Event> GetActive();
void RemoveEvent(Event event);
}
当然水暖它通过以 EventService
,后来终于有内访问 EventsController
。
要拿去[几个]进一步的步骤,你可以看一下依赖注入,您可以指定(一次性)如何建立一个 IEventsService
那么,当你需要它,把它作为参数传递给你的控制器的构造函数(像这样):
To take it [several] steps further, you can look at Dependency Injection where you specify (one time) how to build an IEventsService
then, when you need it, pass it as an argument to your controller's constructor (like so):
public OtherController : Controller
{
private readonly IUserService;
private IEventService eventService;
public OtherController(IUserService userService, IEventService eventService)
{
this.userService = userService;
this.eventService = eventService;
}
/* actions */
}
然后,您可以使用像温莎城堡,ninject,或任何会涉及一个单一的地图,这些接口,然后(神奇),它们提供给您的控制器的构造函数中使用其他解决方案。举个例子,这里有一个Castlewindsor配置:
Then, you can use something like Castle Windsor, ninject, or any of the other solutions that would involve a single map to these interfaces and then (magically) provide them to your controller's constructor for use. To give an example, here's a Castlewindsor configuration:
container.Register(
Component.For<IEventService>().ImplementedBy<EventService>()
.LifestyleSingleton()
);
基本上说,我每次需要 IEventService
供应 EventService
。
这篇关于干实体框架搜索呼叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!