Я бы спонтанно хотел немного отключить зависимость базы данных от объектов. Вы могли бы начать с создания интерфейса, который определяет методы хранения для вашего объекта TestData (в моем примере есть только метод Add, но это, конечно, можно расширить):
public interface ITestDataRepository
{
void Add(TestData data);
}
Следующим шагом является создание класса TestData. Одной из функций этого класса может быть принятие ITestDataRepository в качестве параметра в конструкторе и предоставление метода Add:
public class TestData
{
public TestData(ITestDataRepository repository)
{
Repository = repository;
}
public ITestDataRepository Repository { get; private set; }
public string SomeData { get; set; }
public void Add()
{
if (Repository != null)
{
Repository.Add(this);
}
}
}
Последнее, что нужно сделать, - реализовать механизм данных, который вы хотите использовать. В данном случае это OleDb, но это может быть также Xml, SqlServer или любая другая форма хранения данных:
public class DbTestDataRepository : ITestDataRepository
{
const string InsertionQuery = @"INSERT INTO TEST (TESTDATA) VALUES (?)";
public void Add(TestData data)
{
using (OleDbConnection conn = DbUtil.GetConnection())
using (OleDbCommand command = new OleDbCommand(InsertionQuery, conn))
{
command.Parameters.Add("@p1", OleDbType.BSTR).Value = data.SomeData;
using (OleDbDataReader reader = command.ExecuteReader())
{
// perhaps log something?
}
}
}
}
Приведенный выше дизайн предоставляет несколько различных преимуществ по сравнению с дизайном в вашем вопросе:
- Нет жесткой связи между вашей объектной моделью и конкретной реализацией хранилища; например, вы можете изменить механизм хранения без изменения объекта TestData.
- Это проверяемое; поскольку единственное требование к механизму хранения данных заключается в том, что он реализует интерфейс хранилища, хранилище данных можно легко смоделировать, что облегчает модульное тестирование.
- В этом конкретном коде базы данных объект соединения живет только в течение очень короткого момента, который обычно является рекомендуемым способом сделать это (метод DbUtil.GetConnection - это то, что я «изобрел»; его нет, но обычно нравится централизовать код для настройки соединения, поэтому я не умножаю его на весь код).
Это всего лишь несколько быстрых идей (например, я не тестировал код, кроме как его компиляцию).