LINQ-to-XYZ多态性?

时间:2010-12-17 01:59:44

标签: linq oracle linq-to-sql entity-framework polymorphism

我遇到这样一种情况:客户端要求我们实施数据访问代码,以便根据运行时配置设置使用Oracle或SQL服务器数据库。生产环境使用Oracle,但dev和QA都针对SQL Server实例运行。

(我对此没有任何控制权,或者对于为什么会出现这种情况有任何背景,除了Oracle是他们的BI平台并且dev想要使用SQL Server。)

他们的要求是使用LINQ-to-SQL / LINQ-to-Oracle进行所有数据访问。他们需要支持应用程序并且没有知识可以跳入EF(他们的要求) - 尽管我认为如果我们使用EF也存在同样的问题。

虽然我可以为两个数据库实现LINQ到XYZ类,以便我可以连接到它们,但它们不共享一个公共接口(除了DataContext),所以我真的无法对接口进行编码并插入实际的实现在运行时。

我应该如何处理这个问题?

更新 写完这篇文章之后,我对EF进行了一些调查,在我看来,如果我使用EF也存在同样的问题 - 这将是我的长期目标。

3 个答案:

答案 0 :(得分:0)

快速思考。使用MEF framework并将DAL图层插入其中。然后根据环境(开发,生产,QA),您可以切换到各种DAL层(Oracle,SQL等)。

如果您想了解MEF,here是一个快速介绍。

还有一段时间,我看过Joydip Kanjilal的Generic Data Access Framework。你甚至可以看一下。

答案 1 :(得分:0)

您需要做的是将ORM datacontext封装在您创建的界面中,如IDataContext。

然后在所有DAL之间共享此接口并实现它。如何插入它只是您的偏好,使用建议的MEF或IoC容器。

答案 2 :(得分:0)

为了关闭这个主题,这是我最终做的事情:

我实现了工作单元和存储库模式的组合。工作单元类是消费代码使用的,并公开可以在我的根实体上执行的所有操作。每个根实体有一个UoW。 UoW通过接口使用存储库类。存储库的实际实现取决于所使用的数据访问技术。

所以,例如,如果我有一个客户实体并且我需要支持检索和更新每条记录,我会有类似的东西:

public interface ICustomerManager
{
    ICustomer GetCustomer(Guid customerId);
    void SaveCustomer(ICustomer customer);
}

public class CustomerManager : ICustomerManager
{
    public CustomerManager(ICustomerRepository repository)
    {
        Repository = repository;
    }

    public ICustomerRepository Repository { get; private set; }

    public ICustomer GetCustomer(Guid customerId)
    {
        return Repository.SingleOrDefault(c => c.ID == customerId);
    }

    public void SaveCustomer(ICustomer customer)
    {
        Repository.Save(customer);
    }
}

public interface ICustomerRepository : IQueryable<ICustomer>
{
    void Save(ICustomer customer);
}

我正在使用Inversion of Control框架在运行时将ICustomerRepository实现注入到CustomerManager类中。实现类将在一个单独的程序集中,可以在数据访问技术发生更改时进行交换。我们所关心的是存储库使用上面定义的契约实现每个方法。

作为旁注,为了使用Linq-to-SQL执行此操作,我只创建了一个LinqCustomerRepository类,该类实现了ICustomerRepository,并为生成的ICustomer实现的Customer实体类添加了一个分部类。然后我可以从存储库中返回L2S实体作为UoW的ICustomer接口的实现和调用代码,并且它们将不再是实体源自L2S代码的更明智。