我目前正在为客户端构建一个大型解决方案,其中代码可重用性是关键字,因为不同类型的项目(即网站,WCF服务,WPF等)应该使用完全相同的businesslogic。
现在,我的解决方案如下:
重点是任何表示层(即MVC网站)都将使用businesslogic层,然后使用存储库进行所需的任何数据库事务。
虽然这可以按照我想要的方式工作,但我发现自己经常在实体框架中对抗ObjectContext,因为在查询存储库中的数据时,实体不会转移到businesslogic(这是合乎逻辑的,因为EFs延迟加载)我知道我可以使用.Include(x => x.MyOtherTable)
,但由于数据库相当大,这种方法会迅速膨胀,如果包含的表有很多,查询可能会相当大记录。
然后我创建了一个DbContextManager
类,如下所示:
public static class DbContextManager
{
//Unique context key per request and thread
private static string Key
{
get
{
return string.Format("MyDb_{0}{1}", HttpContext.Current.GetHashCode().ToString("x"), Thread.CurrentContext.ContextID);
}
}
//Get and set request context
private static MyEntities Context
{
get { return HttpContext.Current.Items[Key] as MyEntities ; }
set { HttpContext.Current.Items[Key] = value; }
}
//Context per request
public static MyEntities Current
{
get
{
//if null, create new context
if (Context == null)
{
Context = new MyEntities ();
HttpContext.Current.Items[Key] = Context;
}
return Context;
}
}
//Dispose any created context at the end of a request - called from Global.asax
public static void Dispose()
{
if (Context != null)
{
Context.Dispose();
}
}
}
在我的global.asax中,我在请求结束时处理上下文:
private void Application_EndRequest(object sender, EventArgs e)
{
DbContextManager.Dispose();
}
这很完美,我现在可以在存储库中进行初始数据库调用,然后在businesslogic层中创建businesslogic规则,因为ObjectContext适用于http请求。
但是,当我需要从WCF服务项目(或者一个WPF项目)调用相同的businesslogic方法时,我将无法使用我的DbContextManager类,因为它依赖于HttpContext。
我觉得我现在正在做这个完全错误的事情,而且我正在与实体框架进行一场无休止的战斗。我错过了什么? Entity Framework是否适用于这些类型的解决方案?现在肯定不会那样: - )
非常感谢任何帮助或提示!
提前致谢。
答案 0 :(得分:0)
我在这里感到很困惑。看起来您正在视图层中直接使用实体图层对象。
这通常是一个坏主意。你的模型应该封装这些。您的业务逻辑层应使用您的模型层来构建UI层可以生成/使用的ViewModel和DTO对象。这将允许您将UI层与数据库/实体层完全分离。
这将使您在Web服务层中重复使用业务逻辑变得微不足道。它应该对您的数据库层一无所知。否则,在实体图层中添加或更改字段将对所有UI图层产生直接影响。