.net 如何设计独立于提供者的DAL

.net 如何设计独立于提供者的DAL,.net,data-access-layer,query-builder,provider-independent,.net,Data Access Layer,Query Builder,Provider Independent,我目前正在开发一个查询生成器应用程序,基本上是一个简单的图形界面,允许不懂SQL的用户在数据库上定义各种查询(连接、选择、插入、更新、删除)。我将使用.NET3.5。我的应用程序应该支持多个数据库,它应该与MS-SQL Server、MySQL和Oracle配合使用,因此我希望您能提供有关如何设计独立于提供商的DAL的任何提示或相关讲座的链接 用户将选择数据库服务器、当前服务器上的数据库、提供连接凭据、选择各种表、定义查询(使用一系列组合框)并最终执行有效的查询。当然,在DAL中,我确实希望为每

我目前正在开发一个查询生成器应用程序,基本上是一个简单的图形界面,允许不懂SQL的用户在数据库上定义各种查询(连接、选择、插入、更新、删除)。我将使用.NET3.5。我的应用程序应该支持多个数据库,它应该与MS-SQL Server、MySQL和Oracle配合使用,因此我希望您能提供有关如何设计独立于提供商的DAL的任何提示或相关讲座的链接

用户将选择数据库服务器、当前服务器上的数据库、提供连接凭据、选择各种表、定义查询(使用一系列组合框)并最终执行有效的查询。当然,在DAL中,我确实希望为每个DB提供程序提供方法。我在想一些关于工厂模式的事情

注意:这是一个简单的学校项目,因此我对结果查询的安全性或性能不感兴趣


更新:经过进一步的研究,以及您提供的非常有价值的输入,我决定使用
DbProviderFactory
。ORM会很有趣,但因为我只想要一个查询分析器/生成器,所以我不认为使用它有什么意义。因此,如果您能为我提供一个关于如何使用
DbProviderFactory
和相关类的详细教程,我将不胜感激。

我认为ADO.NET实体框架(从.NET 3.5 SP1开始提供)是一个很好的选择,因为它用实体SQL语言抽象出依赖数据库的SQL。

我认为ADO.NET实体框架(从.NET 3.5 SP1开始提供)是一个很好的选择,因为它用实体SQL语言抽象出依赖数据库的SQL。

您可能会感到惊讶,但是一个非常简单的独立于提供者的DAL可以通过普通的旧的
数据集
数据表
实现,您可能会感到惊讶,但是一个非常简单的独立于提供者的DAL可以通过普通的旧的
实现。我必须说,可视化地编辑一个相当复杂的查询是非常麻烦的。允许用户使用VisualDesigner插入/删除数据是一种打击自己的方式。作为一个缩小版的ManagementStudio,了解基本SQL和受限服务器用户将做得更好


如果你仍然倾向于设计这个应用程序,你需要NHibernate。更准确地说,将完成这项工作,因为它们与您需要的内容非常接近。

我必须说,可视化地编辑一个相当复杂的查询非常麻烦。允许用户使用VisualDesigner插入/删除数据是一种打击自己的方式。作为一个缩小版的ManagementStudio,了解基本SQL和受限服务器用户将做得更好

如果你仍然倾向于设计这个应用程序,你需要NHibernate。更准确地说,将完成这项工作,因为它们的映射非常接近您的需要。

大多数ORM(对象关系映射器)都知道如何与各种数据库类型进行通信

至于允许用户构建自己的查询,您需要非常小心。与其说用户可以创建恶意查询(尽管这可能是个问题),不如说这是个意外。编写使用所有可用服务器资源并为数据库创建有效拒绝服务的查询非常容易。

大多数ORM(对象关系映射器)都知道如何与各种数据库类型进行对话


至于允许用户构建自己的查询,您需要非常小心。与其说用户可以创建恶意查询(尽管这可能是个问题),不如说这是个意外。编写使用所有可用服务器资源并为数据库创建有效拒绝服务的查询非常容易。

我建议使用
System.Data.Common.dbProviderFactorys
类生成通用ADO.NET类

当您找到更多要支持的数据库的.NET提供程序时,只需在应用程序路径中删除提供程序DLL,并在
app.config
文件中添加对提供程序的
DbProviderFactory
的引用。您可以让用户选择要使用的提供程序

下面是一篇MSDN文章,主题是

我以前使用过这种方法,并且能够在同一个项目中支持MSSQL和SQLite,只需稍作配置更改


不确定它是否适用于查询生成器应用程序,但是…

我建议使用
System.Data.Common.dbProviderFactorys
类生成通用ADO.NET类

当您找到更多要支持的数据库的.NET提供程序时,只需在应用程序路径中删除提供程序DLL,并在
app.config
文件中添加对提供程序的
DbProviderFactory
的引用。您可以让用户选择要使用的提供程序

下面是一篇MSDN文章,主题是

我以前使用过这种方法,并且能够在同一个项目中支持MSSQL和SQLite,只需稍作配置更改


不确定,它是否也适用于查询生成器应用程序,尽管…

我不确定这是否有助于您的搜索,但我最近学到的一件事是,让您的数据模型的唯一标识符实现不直接传播到数据层之外,而是包装在抽象中。例如,下面是一个包装模型标识符的接口:

public interface IModelIdentifier<T> where T : class 
{
    /// <summary>
    /// A string representation of the domain the model originated from.
    /// </summary>
    string Origin { get; }

    /// <summary>
    /// The model instance identifier for the model object that this 
    /// <see cref="IModelIdentifier{T}"/> refers to.  Typically, this 
    /// is a database key, file name, or some other unique identifier.
    /// <typeparam name="KeyDataType">The expected data type of the 
    /// identifier.</typeparam>
    /// </summary>
    KeyDataType GetKey<KeyDataType>();

    /// <summary>
    /// Performs an equality check on the two model identifiers and 
    /// returns <c>true</c> if they are equal; otherwise <c>false</c> 
    /// is returned.  All implementations must also override the equal operator.
    /// </summary>
    /// <param name="obj">The identifier to compare against.</param>
    /// <returns><c>true</c> if the identifiers are equal; otherwise 
    /// <c>false</c> is returned.</returns>
    bool Equals(IModelIdentifier<T> obj);
}
然后,您的数据层将有一个类,该类实现
imodeIdentifier
,并用物理模型的唯一标识符填充其内部数据类型。这将使您的业务层不受数据层的任何更改的影响,例如用
Gui替换
int
键标识符
    public IPerson RetrievePerson(IModelIdentifier<IPerson> personId)
    {
        /// Retrieval logic here...
    }