我是开发抽象工厂模式的新手,并希望在数据层中创建一个抽象工厂,它将帮助我将此层链接到任何其他数据库,例如sql和oracle。你能帮我完成这项任务吗?请注意,数据库的连接字符串将在此层中找到,而不是在演示文稿中。
由于
EDITED
public abstract class Database
{
public string connectionString;
#region Abstract Functions
public abstract IDbConnection CreateConnection();
public abstract IDbCommand CreateCommand();
public abstract IDbConnection CreateOpenConnection();
public abstract IDbCommand CreateCommand(string commandText, IDbConnection connection);
public abstract IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection);
public abstract IDataParameter CreateParameter(string parameterName, object parameterValue);
#endregion
}
public class SQLDatabase : Database
{
public override IDbConnection CreateConnection()
{
return new SqlConnection(connectionString);
}
public override IDbCommand CreateCommand()
{
return new SqlCommand();
}
public override IDbConnection CreateOpenConnection()
{
SqlConnection connection = (SqlConnection)CreateConnection();
connection.Open();
return connection;
}
public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
{
SqlCommand command = (SqlCommand)CreateCommand();
command.CommandText = commandText;
command.Connection = (SqlConnection)connection;
command.CommandType = CommandType.Text;
return command;
}
public override IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection)
{
SqlCommand command = (SqlCommand)CreateCommand();
command.CommandText = procName;
command.Connection = (SqlConnection)connection;
command.CommandType = CommandType.StoredProcedure;
return command;
}
public override IDataParameter CreateParameter(string parameterName, object parameterValue)
{
return new SqlParameter(parameterName, parameterValue);
}
}
这是我创建的两个课程。
答案 0 :(得分:8)
功能已存在。
将连接字符串添加到app / webb.config:
<connectionStrings>
<add name="TheDatabase" providerName="System.Data.OleDb" connectionString="Provider=OraOLEDB.Oracle.1;Persist Security Info=False;User Id=xxx;Password=yyy;Data Source=zzzz;Extended Properties="/>
</connectionStrings>
使用工厂建立连接:
var connectionString = ConfigurationManager.ConnectionStrings["TheDatabase"];
var providerName = connectionString.ProviderName;
var factory = DbProviderFactories.GetFactory(providerName);
获取连接:
var connection = factory.CreateConnection();
获取命令:
var command == connection.CreateCommand();
您唯一需要做的就是在app / web.config中切换驱动程序。不需要进行其他更改。
public class Database
{
public static IDbConnection CreateOpenConnection()
{
var connectionString = ConfigurationManager.ConnectionStrings["TheDatabase"];
var providerName = connectionString.ProviderName;
var factory = DbProviderFactories.GetFactory(providerName);
var connection = factory.CreateConnection();
connection.Open();
return connection;
}
}
class FlowerManager : DataWorker
{
public static void GetFlowers()
{
using (IDbConnection connection = Database.CreateOpenConnection())
{
using (IDbCommand command = connection.CreateCommand("SELECT * FROM FLOWERS", connection))
{
using (IDataReader reader = command.ExecuteReader())
{
// ...
}
}
}
}
}
答案 1 :(得分:4)
可以从
获得许多所需的功能 System.Data.Common.DbProviderFactories
您可以获取大多数dotnet-databaseproviders实现的System.Data.Common.DbProviderFactory
项。
<强>更新强>:
havig你自己的工厂很好。如果您想了解工作数据库工厂的示例,请参阅的源代码答案 2 :(得分:0)
我没有“createcommand”或“createconnection”方法。
更好的方法是让每个访问方法(如“GetAccounts”)处理自己的连接/命令实例化。
Connection和Command对象实现IDisposable。因此,最好使用using语句来创建和处理这些语句。你现在拥有它可能会导致大量内存问题。
此外,CreateParameter方法似乎没有提供任何真正的好处,而只是在需要创建这些参数的代码中调用“new SqlParameter”。
我会做以下事情:
public interface IDbAccess {
String ConnectionString;
Collection<Account> GetAccountsById(Int32 id);
Boolean StoreAccount(Account acct);
}
public class SqlDatabase : IDbAccess {
public String ConnectionString {get; set;}
public SqlDatabase(String connection) {
ConnectionString = connection;
}
public Collection<Account> GetAccountsById(Int32 id) {
using (SqlConnection connect = new SqlConnection(ConnectionString)) {
using (SqlCommand cmd = new SqlCommand(connect)) {
/// etc.
}
}
}
}
这样,您的数据层特定于您提供的功能。像Enterprise Library这样的db访问已有很好的包装器。你采取的方法不会增加任何内容并引入错误。
此外,这种方法意味着您可以实现非数据库提供程序,如XML,Web服务等,无需更改代码。
答案 3 :(得分:0)
嗨,大家好我知道这是老帖子,但我想和你分享一些东西。
企业库和OleDb有一些问题,当你想要插入大于32k的图像时,它会抛出异常,所以我已经完成了解决这个问题:
创建一个项目,您可以调用CustomProvider
创建一个Classe,您将其称为数据库
public abstract class Database
{
public string ConnectionString { get; set; } // Preciso uma variavel para guardar o ConnectionString
public IDbConnection Connection { get; set; }
//public abstract string ProviderName { get; } // Preciso uma variavel para guardar o ConnectionString
//public abstract IDbConnection CreateConnection(string ConnectionString);
public abstract IDbConnection CreateConnection(); // Preciso um Metodo Abstract para CreateConnection Para Tratar da Connection
public abstract IDbCommand CreateCommand();
}
}
OracleDatabase.cs
创建第三课SQLDatabase.cs
public class OracleDatabase : Database
{
public override IDbConnection CreateConnection()
{
return new OracleConnection(ConnectionString);
}
public override IDbCommand CreateCommand()
{
return new OracleCommand();
}
public override IDbConnection CreateOpenConnection()
{
OracleConnection connection = (OracleConnection)CreateConnection();
connection.Open();
return connection;
}
public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
{
OracleCommand command = (OracleCommand)CreateCommand();
command.CommandText = commandText;
command.Connection = (OracleConnection)connection;
command.CommandType = CommandType.Text;
return command;
}
}
public class SQLDatabase:Database {
public override IDbConnection CreateConnection()
{
return new SqlConnection(ConnectionString);
}
public override IDbCommand CreateCommand()
{
return new SqlCommand();
}
public override IDbConnection CreateOpenConnection()
{
SqlConnection connection = (SqlConnection)CreateConnection();
connection.Open();
return connection;
}
public override IDbCommand CreateCommand(string commandText, IDbConnection connection)
{
SqlCommand command = (SqlCommand)CreateCommand();
command.CommandText = commandText;
command.Connection = (SqlConnection)connection;
command.CommandType = CommandType.Text;
return command;
}
public override IDbCommand CreateStoredProcCommand(string procName, IDbConnection connection)
{
SqlCommand command = (SqlCommand)CreateCommand();
command.CommandText = procName;
command.Connection = (SqlConnection)connection;
command.CommandType = CommandType.StoredProcedure;
return command;
}
}
然后是程序
Database db = Factory.CreateDatabase("ConnectionString");
try
{
using (IDbConnection w_connection = db.Connection)
{
w_connection.Open();
IDbTransaction transation = w_connection.BeginTransaction();
IDbCommand dbcomand = db.CreateStoredProcCommand("INSERTTEST");
db.AddInParameter(dbcomand, "@ATTCH", DbType.Binary, bytes);
db.ExecuteNonQuery(dbcomand, transation);
transation.Commit();
}
}
catch (Exception)
{
}
}
您必须覆盖主类中所有已定义的方法
创建 Factory.cs
public static Database CreateDatabase(string ConnectionString)
{
//var Conn = ConfigurationManager.ConnectionStrings[ConnectionString].ToString();
if (string.IsNullOrEmpty(ConnectionString))
throw new Exception("Connectionstring Not Found" + ConnectionString);
Database db = null;
if (ConfigurationManager.ConnectionStrings[ConnectionString].ProviderName.Contains("Oracle"))
{
db = new OracleDatabase();
db.ConnectionString = GetConnectionString(ConnectionString);
db.Connection = db.CreateConnection();
}
else
{
db = new SQLDatabase();
db.ConnectionString = GetConnectionString(ConnectionString);
db.Connection = db.CreateConnection();
}
return db;
}