C# 与数据库无关的ASP.Net?
我们正在制作一个ASP.Net应用程序。我们希望我们的应用程序至少与sorta DB无关,最值得注意的是与SQL Server和PostgreSQL兼容。这样做的最佳方式是什么?常见的陷阱有哪些?还有一个类或其他东西已经抽象出了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)您可以使
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
在非常高的级别上,您可能希望使用一些抽象数据库的东西,而不仅仅是SqlConnection、SqlCommand和Sql*类。所以当人们说要使用ORMs时,他们几乎是对的。ORMs为您提供了这种抽象级别
但是为了抽象出SqlCommand和SqlConnection,System.Data命名空间中有一些接口。IDbConnection、IDbCommand等已经在框架内,您可以针对这些内容编写代码。接下来的问题是找到创建具体类的方法,您可以使用IoC容器或提供程序模式来解决这个问题。所有ADO.Net提供程序都扩展了基本接口:
一种更可行的方法是满足多个目标目的地并开发特定的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解决方案,因为他们对如何获取数据提出了要求,我可以使用存储过程吗?如果需要,我可以进行多个数据库调用吗?