Возвращение путаницы к объектам
У меня есть некоторый код электронной коммерции, который я часто использую, который использует Linq To SQL для сохранения заказов в базе данных. Я хочу удалить тесно связанный бит Linq to SQL и передать вместо него IRepository, но я все еще немного сбит с толку.
Скажем, у меня есть метод GetCustomer() в моем ICustomerRepository, который возвращает объект Customer.
Нужно ли мне действительно возвращать объект ICustomer, который возвращается из этого метода, поэтому, если я переключаюсь с Linq на SQL, чтобы сказать SubSonic, это не проблема?
Я верю, что если да, то есть ли в Linq To SQL способ легко преобразовать мой объект Linq To SQL Customer в мой объект ICustomer, такой как метод SubSonics ExecuteSingle(Of)?
3 ответа
Если вы хотите, чтобы ваш класс Customer был простым объектом без привязки к LINQ, вам, скорее всего, потребуется написать метод mapper для преобразования вашего объекта Customer на основе LINQ в ваш простой объект домена Customer. LINQ to SQL не имеет такой встроенной функциональности.
Я начал оборачивать свои методы отображения в метод расширения для удобства чтения, и это действительно помогает сохранить простой код репозитория. Например, пример метода CustomerRepository, который может выглядеть следующим образом:
public Customer GetById(int id)
{
return dataContext.LINQCustomers.Where(c => c.Id == id)
.Single()
.ToDomainObject();
}
и метод ToDomainObject() определен в методе расширения, например:
public static class ObjectMapper
{
public static Customer ToDomainObject(this Customer linqObject)
{
var domainObject = null
if (linqObject != null)
{
domainObject = new Customer
{
Id = linqObject.Id,
FirstName = linqObject.FirstName,
LastName = linqObject.LastName
}
}
return domainObject;
}
}
или что-то подобное. Вы можете сделать то же самое, чтобы преобразовать ваш доменный объект обратно в объект LINQ для передачи обратно в ваш репозиторий для сохранения.
Вы можете сделать так, чтобы он возвращал Customer до тех пор, пока Customer является простым старым объектом.NET, а не какой-либо созданной БД сущностью. Ваш объект домена Customer не должен знать о том, как (или если) он может быть сохранен в базе данных, и это то, что должно быть возвращено из вашего хранилища. В вашем репозитории у вас может быть некоторый код отображения - это довольно часто - который сопоставляется с [как бы вы ни возвращали данные из его хранилища] вашему объекту домена. Если вы используете Linq-to-sql, то это сопоставление будет происходить из таблицы Customer, сгенерированной Linq-To-Sql (и, возможно, других таблиц - ваш объект домена Customer, скорее всего, не будет отображать 1:1 для конкретной таблицы в базе данных.) к вашему доменному объекту Customer, который будет находиться в другом пространстве имен (и, скорее всего, в сборке).
Нет нужды делать из этого ICustomer. Репозиторий действует таким образом, что выглядит как будто ваши постоянные экземпляры находятся в памяти.
public interface ICustomerRepository
{
Customer GetByID(int id);
IEnumerable<Customer> GetByName(string name);
Customer GetByVatCode(string vatCode);
}
Некоторые люди дополнительно включают такие методы, как
void Add(Customer newCustomer);
void Delete(Customer deleted);
void Update(Customer modified);
Последние реализации метода, скорее всего, просто обновят единицу работы.
Концепция заключается в том, что это всего лишь распространенные способы запроса экземпляров Customer, а хранилище действует как способ запроса их, не определяя, как их запрашивать.