0

我目前正在开发一个查询生成器应用程序,基本上是一个简单的图形界面,应该允许用户不知道SQL来定义数据库上的各种查询(连接,选择,更新,插入,删除)。我将使用.Net 3.5。我的应用程序应该支持多个数据库,它应该可以和MS-SQL Server,MySQL和Oracle一起工作,所以我会很感激任何关于相关讲座的提示或链接,如何设计一个独立于提供程序的DAL如何设计一个提供者独立DAL(.Net)

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

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

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

回答

2

我推荐使用System.Data.Common.DbProviderFactories类来生成通用的ADO.NET类。

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

这里是关于主题的MSDN文章:Obtaining a DbProviderFactory (ADO.NET)

我用这个方法前,已经能够支持MSSQL和SQLite与少量的配置变化在同一个项目。

不知道是否会为一个查询生成器应用程序的工作,虽然还有...

0

我认为ADO.NET实体框架(从.NET 3.5 SP1开始可用)是一个很好的选择,因为它几乎将实体SQL语言抽象为与数据库相关的SQL。

+0

截止目前,ADO.NET EF仅支持Microsofts的DBMS。 – 2009-04-21 13:10:30

+0

实体仅适用于MS SQL Server。 – kjv 2009-04-21 13:11:45

0

你可能会惊讶,但一个很简单的供应商独立DAL可以实现:

老式的DataSet的DataTable

0

我必须说,编辑一个合理复杂的查询视觉上是繁琐。并允许用户使用视觉设计师插入/删除数据是一种在脚下拍摄自己的特定方式。一个缩小版的Management Studio,基本的SQL和受限制的服务器用户的知识将会做得更好。

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

0

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

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

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

你的业务逻辑层,这可能对周围int S作为唯一标识符传递(例如在过去,从标识列),现在通过这样:然后

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

你的数据层将具有它实现IModelIdentifier<Person>并填充与物理模型的唯一标识符其内部数据类型的类。这将业务层与数据层可能发生的任何更改隔离开来,例如用Guid s替换int密钥标识符。