#c# #linq-to-sql #subclass
#c# #linq-to-sql #подкласс
Вопрос:
Я хотел бы иметь возможность подклассировать автоматически созданные классы данных LINQ для SQL и сохранять изменения в указанных объектах.
Например, если у меня есть таблица Client
в моей базе данных, я могу создать, ClientBO
которая расширяет класс Client
и добавляет такие параметры поведения, как GenerateInvoice()
или что-то еще. Все работает нормально, пока я не захочу обновить значения в подклассе или вставить новую запись. Такие изменения (предсказуемо?) отбрасываются. Я чего-то не хватает, или я нарушаю принцип LINQ to SQL или OO, создавая эти подклассы в первую очередь?
Ниже приведены упрощенные примеры моего кода:
public class ClientBO : Client
{
public ClientBO( Client source ) : base()
{
FirstName = source.FirstName;
Lastname = source.LastName;
// ... etc ...
}
}
List<ClientBO> clientList =
( from client in DatabaseContext.Clients select new ClientBO( client ) ).ToList();
clientList[ someIndex ].SomeField = NewValue;
MyDatabaseContext.SubmitChanges();
Ответ №1:
Проблема в том, что объект, который вы изменяете, больше не является тем же объектом, который получен из хранилища данных.
DataContext отслеживает изменения во всех объектах, которые он прикрепил. Но поскольку вы никогда не изменяете «исходный» объект, на который ссылаетесь, контекст данных никогда не уведомляется об изменении
Я бы посоветовал вам вместо этого создать свой ClientBO
частичный класс Client
(конечно, переименовав его в Client). Все классы Linq-To-Sql генерируются как частичные, и, таким образом, вы можете легко расширить их таким образом
Вот так:
public partial class Client
{
public void GenerateInvoice()
{
// ... etc ...
}
}
List<Client> clientList = MyDatabaseContext.Clients.ToList();
clientList[ someIndex ].SomeField = NewValue;
MyDatabaseContext.SubmitChanges();
Комментарии:
1. 1 И ваш, и Хогана — отличные подходы, которые я должен был рассмотреть в первую очередь. Я придерживаюсь вашего, потому что это предполагает наименьшие изменения в моей существующей инфраструктуре.
2. 1 я думаю, что это правильный путь. Возможно, вы захотите пересмотреть добавление «GenerateInvoice» в класс Client, хотя 🙂 но дело здесь не в этом
3. @Pleun — GenerateInvoice() был абстрактным примером, и при этом, по общему признанию, ужасным примером.
Ответ №2:
Я думаю, что вам действительно нужны здесь некоторые методы расширения:
http://msdn.microsoft.com/en-us/library/bb383977.aspx
Они будут выглядеть так, как будто они являются частью класса, но вы реализуете их в другом модуле. Именно то, что вы хотите.
Комментарии:
1. 1 Подходят как ваши, так и Oskar. Oskar предполагает меньшее количество изменений в моей существующей инфраструктуре. Однако я должен был рассмотреть это в первую очередь.