1

我目前正在开发一个查询构建器应用程序,基本上是一个简单的图形界面,它应该允许不了解 SQL 的用户在数据库上定义各种查询(连接、SELECT、INSERT、UPDATE、DELETE)。我将使用 .NET 3.5。我的应用程序应该支持多个数据库,它应该与 MS-SQL Server、MySQL 和 Oracle 一起使用,所以我希望能提供任何提示或链接到有关如何设计独立于提供程序的 DAL 的相关讲座。

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

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

更新:经过更多研究和您提供的非常有价值的输入,我决定使用DbProviderFactory. ORM 会很有趣,但是因为我只想要一个查询分析器/构建器,所以我看不出使用它的意义。因此,如果您能向我指出有关如何使用DbProviderFactory和相关类的详细教程,我将不胜感激。

4

6 回答 6

3

我建议使用System.Data.Common.DbProviderFactories该类来生成通用 ADO.NET 类。

当您找到更多要支持的数据库的 .NET 提供程序时,只需将提供程序 DLL 拖放到应用程序的路径中,然后DbProviderFactoryapp.config文件中添加对提供程序的引用即可。您可以让用户选择要使用的提供程序。

这是一篇关于获取一个DbProviderFactory(ADO.NET)主题的 MSDN 文章

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

不确定,但它是否适用于查询构建器应用程序......</p>

于 2009-04-21T13:00:30.003 回答
1

您可能会感到惊讶,但可以使用普通的旧版本DataSetDataTable.

于 2009-04-21T12:47:25.293 回答
1

我必须说,在视觉上编辑一个相当复杂的查询非常麻烦。并且允许用户使用可视化设计器插入/删除数据是一种自取其辱的方式。精简版的 Management Studio、基本 SQL 知识加上受限服务器用户会做得更好。

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

于 2009-04-21T12:50:48.157 回答
0

我认为 ADO.NET Entity Framework(从 .NET 3.5 SP1 开始可用)是一个很好的选择,因为它几乎用它的实体 SQL 语言抽象了依赖于数据库的 SQL。

于 2009-04-21T12:46:48.103 回答
0

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

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

于 2009-04-21T12:51:21.900 回答
0

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

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);
}

您的业​​务逻辑层过去可能将ints 作为唯一标识符传递(例如,来自数据库表中的标识列),现在这样传递:

    public IPerson RetrievePerson(IModelIdentifier<IPerson> personId)
    {
        /// Retrieval logic here...
    }

然后,您的数据层将有一个类,IModelIdentifier<Person>该类使用物理模型的唯一标识符实现并填充其内部数据类型。这将您的业务层与您在数据层可能进行的任何更改隔离开来,例如int用 s 替换您的密钥标识符Guid

于 2009-04-21T15:26:55.893 回答