Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与数据库无关的ASP.Net?_C#_Asp.net_Sql Server_Postgresql_Portability - Fatal编程技术网

C# 与数据库无关的ASP.Net?

C# 与数据库无关的ASP.Net?,c#,asp.net,sql-server,postgresql,portability,C#,Asp.net,Sql Server,Postgresql,Portability,我们正在制作一个ASP.Net应用程序。我们希望我们的应用程序至少与sorta DB无关,最值得注意的是与SQL Server和PostgreSQL兼容。这样做的最佳方式是什么?常见的陷阱有哪些?还有一个类或其他东西已经抽象出了SqlConnection和PostgreSQL用于连接的任何东西之间的区别吗 (我们希望不依赖数据库,因此我们可以在这里使用PostgreSQL(正在开发中,稍后在我们自己的托管中),因为价格太高,如果我们的自托管客户端愿意,可以让他们使用Sql Server)您可以使

我们正在制作一个ASP.Net应用程序。我们希望我们的应用程序至少与sorta DB无关,最值得注意的是与SQL Server和PostgreSQL兼容。这样做的最佳方式是什么?常见的陷阱有哪些?还有一个类或其他东西已经抽象出了
SqlConnection
和PostgreSQL用于连接的任何东西之间的区别吗


(我们希望不依赖数据库,因此我们可以在这里使用PostgreSQL(正在开发中,稍后在我们自己的托管中),因为价格太高,如果我们的自托管客户端愿意,可以让他们使用Sql Server)

您可以使用实体框架。这样,您就可以使用单一的编程模型


我只是为我的数据源创建一个接口,然后为我需要使用的每个数据源类型实现它。通常它们看起来像这样:

public interface IMyProjectDataSource
{
    IEnumerable<string> GetUserNames();
    void AddUser(string userName);
}

public class SqlServerMyProjectDataSource : IMyProjectDataSource
{
    public SqlServerMyProjectDataSource(string connectionString)
    {
        //...
    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

public class PostgreSqlMyProjectDataSource : IMyProjectDataSource
{

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
    public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
    {

    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}
public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
    public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
    {
            //...
    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}
公共接口IMyProjectDataSource
{
IEnumerable GetUserNames();
void AddUser(字符串用户名);
}
公共类SqlServerMyProjectDataSource:IMyProjectDataSource
{
公共SqlServerMyProjectDataSource(字符串连接字符串)
{
//...
}
public IEnumerable GetUserNames()
{
//...
}
public void AddUser(字符串用户名)
{
//...
}
}
公共类PostgreSqlMyProjectDataSource:IMyProjectDataSource
{
public IEnumerable GetUserNames()
{
//...
}
public void AddUser(字符串用户名)
{
//...
}
}
公共类HttpCacheSqlMyProjectDataSource:IMyProjectDataSource
{
公共HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
{
}
public IEnumerable GetUserNames()
{
//...
}
public void AddUser(字符串用户名)
{
//...
}
}
我也喜欢这个,因为它可以让你把它们“链”在一起。例如,您可以像这样执行所有数据源缓存:

public interface IMyProjectDataSource
{
    IEnumerable<string> GetUserNames();
    void AddUser(string userName);
}

public class SqlServerMyProjectDataSource : IMyProjectDataSource
{
    public SqlServerMyProjectDataSource(string connectionString)
    {
        //...
    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

public class PostgreSqlMyProjectDataSource : IMyProjectDataSource
{

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
    public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
    {

    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}
public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
    public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
    {
            //...
    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}
公共类HttpCacheSqlMyProjectDataSource:IMyProjectDataSource { 公共HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource) { //... } public IEnumerable GetUserNames() { //... } public void AddUser(字符串用户名) { //... } } 最困难的部分是决定如何创建它,特别是如果您计划将多个链接在一起。为此,我通常将其作为单例存储在Global.asax.cs中,并从.config文件中的类型名创建它。您可以使用Type.GetType()然后使用Activator.CreateInstance()来实现这一点,并且无论.config中的数据源是什么,我所拥有的大部分链接都将完成,因此我不必担心创建某种“构造函数”类型或复杂的.config


希望这是有道理的。这可能不是所有情况下的最佳选择,但我很幸运。正如设拉子所提到的,实体框架是一种选择。您也可以考虑其他ORM解决方案,例如.< /P> < P>数据库不可知应用程序的最佳解决方案通常是()。对于.NET来说,有很多方法可以帮助您选择

三个最受欢迎的是:

  • (现在由取代)-由Stackoverflow.com使用。仅限SQL Server

我建议使用某种存储库模式

这并不是一个可以让您免于对每种DBMS风格进行黑客攻击的灵丹妙药,但如果您希望从一开始就可以对其进行维护,这是ORMs无法提供的


在非常高的级别上,您可能希望使用一些抽象数据库的东西,而不仅仅是SqlConnection、SqlCommand和Sql*类。所以当人们说要使用ORMs时,他们几乎是对的。ORMs为您提供了这种抽象级别


但是为了抽象出SqlCommand和SqlConnection,System.Data命名空间中有一些接口。IDbConnection、IDbCommand等已经在框架内,您可以针对这些内容编写代码。接下来的问题是找到创建具体类的方法,您可以使用IoC容器或提供程序模式来解决这个问题。

所有ADO.Net提供程序都扩展了基本接口:

因此,从理论上讲,您可以根据抽象接口编写整个DAL(数据访问层),并利用任何提供商,包括像MySQLs这样的第三方提供商。实际上,没有一个凡人能做到这一点。一方面,这些接口很难编程,任何应用程序在演示软件之外都会很快遇到SQL方言不兼容的问题


一种更可行的方法是满足多个目标目的地并开发特定的DAL。实体框架和存储库模式以及nHibernate和所有此类帮助,但都不能解决基本问题。

如果您只想直接使用ADO.NET,可以使用DbProviderFactory抽象出您正在使用的提供程序(SqlClient、OleDb等)。通常将其与配置元素结合使用,代码如下:

ConnectionStringSettings c = ConfigurationManager.ConnectionStrings[name];
DbProviderFactory factory = DbProviderFactories.GetFactory(c.ProviderName)
...
IDbConnection connection = _factory.CreateConnection();
connection.ConnectionString = c.ConnectionString;
...
MSDN中有很多信息


当然,这并不能帮助您解决不同提供程序之间SQL语法的差异——您需要一种最小公分母的方法来处理多个提供程序。这会影响参数的语法(例如SQL Server的@prefix、仅OleDb的位置参数等)。

这是一个DAL(数据访问层)。这是一个很好的设计概念,但仍然会给您带来实现每种存储类型的负担。ORM解决方案减轻了您的负担(尽管它们也有缺点)。我不太喜欢大多数ORM解决方案,因为他们对如何获取数据提出了要求,我可以使用存储过程吗?如果需要,我可以进行多个数据库调用吗?