n层项目

时间:2015-04-22 19:46:29

标签: c# asp.net-mvc entity-framework wcf n-tier-architecture

我目前正在为客户端构建一个大型解决方案,其中代码可重用性是关键字,因为不同类型的项目(即网站,WCF服务,WPF等)应该使用完全相同的businesslogic。

现在,我的解决方案如下:

  • Businesslogic图层(此处添加了定义业务规则的所有逻辑)
  • 接口
  • 模型(ViewModels,DTO等)
  • 存储库(目前正在使用实体框架6.这是所有数据库事务的去处)
  • Webservices(WCF服务)
  • MVC网站

重点是任何表示层(即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是否适用于这些类型的解决方案?现在肯定不会那样: - )

非常感谢任何帮助或提示!

提前致谢。

1 个答案:

答案 0 :(得分:0)

我在这里感到很困惑。看起来您正在视图层中直接使用实体图层对象。

这通常是一个坏主意。你的模型应该封装这些。您的业​​务逻辑层应使用您的模型层来构建UI层可以生成/使用的ViewModel和DTO对象。这将允许您将UI层与数据库/实体层完全分离。

这将使您在Web服务层中重复使用业务逻辑变得微不足道。它应该对您的数据库层一无所知。否则,在实体图层中添加或更改字段将对所有UI图层产生直接影响。