建立DAL。使用EDM(来自数据库)

时间:2014-02-18 17:57:18

标签: c# wcf entity-framework visual-studio-2012

我必须开发一个在windows(wpf)中运行的lob应用程序,但应该以两种方式部署:

  • 使用本地数据库(同一台计算机)
  • 使用远程数据库(在同一网络中)

我将使用从数据库生成的实体数据模型(dbcontext,EF 4.0)(VS2012,sql server express 2012)

我想开发一个UI绑定的唯一数据访问层,它将直接从dbcontext(本地数据库)或从dbcontext(远程数据库)公开数据的WCF服务获取数据

enter image description here

我不知道从哪里开始,我需要指导,示例,我知道这取决于应用程序的性质,但是一些示例文章将会有很大的帮助。我没有找到与我的需求相似的例子

我想我最好使用DI框架,但我想首先关注DAL。

2 个答案:

答案 0 :(得分:0)

好吧,既然您想使用DI框架(可能是一个不错的选择:)),您已经知道需要使用接口定义DAL。然后,您可以拥有实现这些接口的类,这些接口充当WCF服务或数据库上下文的适配器。

您的设计的一个不错的方面是,您将自动将自己与未来可能的WCF服务替代品隔离开来。数据库上下文 - 即每当Microsoft发布另一种数据访问技术时。 :)或者更有可能的是,只要您的团队决定采用不同的团队,例如从WCF服务切换到REST服务。

通常,Repository pattern用于解决此问题。例如,你可能有:

public interface IWidgetRepository
{
    // Query methods
    Widget GetById(string id);
    IEnumerable<Widget> GetAll();

    // Update methods
    void RenameWidget(string id, string newName);
    void UpdateWidgetPrice(string id, decimal newPrice);
}

如果您尝试使存储库接口非常通用,那么当您开始意识到您希望具有不同的查询功能等时,这会变得非常艰巨(例如,如果您尝试在DAL中实现IQueryable,你已经有很多工作要做了!我已经尝试了,我放弃了意识到我只是在浪费精力。)

解决这个问题的最佳方法可能是使用预定义的查询方法,例如: GetWidgetsWithOpenOrders()GetWidgetsWithFooBarComponents。然后在实现IWidgetRepository的适配器类中,您只需通过将它们映射到实体框架或WCF服务实现来实现这些查询。

这样做的一个副作用是DAL需要它自己的一组数据传输对象(DTO) - 所以你最终会在DAL命名空间中找到一个Widget类,并且可能在数据库中有其他Widget类上下文和/或WCF服务代理。您可以尝试通过强制DB Context为其数据库映射使用相同的Widget类来解决这个问题,但我不建议这样做。数据库上下文中的DTO适用于数据库,WCF服务中的DTO也是如此 - 它们是服务公开的数据协定。 DAL中的DTO用于反映用户界面的需求(在MVVM术语中,它们是'模型';在OO模式术语中,它们对于不同的数据访问策略是Façade。 / p>

另一个副作用是,很容易为1)单元测试创​​建IWidgetRepository的存根/模拟实现,2)在没有完全实现后端数据访问策略的情况下快速进行UI原型设计。 / p>

答案 1 :(得分:0)

实现面向服务的体系结构,您的UI将根据用户或应用程序设置使用不同的服务,因此实例化访问本地数据库或WCF服务的不同DAL对象...

-Contract

namespace MyUIName.Services
{
    public interface IProductServiceAgent
    {
        List<Product> GetProducts();
    }
}

智能体

namespace MyUIName.Services
{
    public class ProductServiceAgent : BaseServiceAgent, IProductServiceAgent
    {
        //Contract implementation
        public List<Product> GetProducts()
        {
            if (Settings.Default.StoreType == "Local")
            {
                LocalStoreBIObject = new...
                LocalStoreBIObject.GetProducts();
            }
            if (Settings.Default.StoreType == "Remote")
            {
                RemoteStoreBIObject = new...
                RemoteStoreBIObject.GetProducts();
            }
        }
    }
}

-BI图层

namespace BI
{
    public class LocalStoreBIObject
    {
        public List<Product> GetProducts()
        {
            //Do some BI stuff.
            //Instantiate appropriate DAL object
            return LocalStoreDALObjec.GetProducts(... pass in some BI params);
        }
    }
}

-DAL Layer

namespace DAL
{
    public class LocalStoreDALObject
    {
        public List<Product> GetProducts()
        {
            using (var localStoreContex = new...)
            {
                return localStoreContext.Products.Where(p => p... some logic);
            }
        }
    }
}

通过这种方式,您可以获得具有BI和DAL层的标准3层体系结构,这使您可以将业务逻辑保持在一个层中,将数据访问逻辑和查询保存在单独的层中,并且服务代理可以决定使用哪个BI层对象取决于应用程序设置。另一个好处是,如果您需要该功能,这也可以让您的用户在运行时切换数据存储......

显然,您不会在DAL层中的BI图层中引用Product类,因此您必须创建一些中间对象或在BI中使用您的EF模型或使用元组将数据从DAL传输到BI层或找到其他解决方案,但这只是您必须在此过程中解决的一个细节......