Как отслеживать изменения в бизнес-объектах? - PullRequest
7 голосов
/ 17 сентября 2008

Я получаю концепцию создания бизнес-объекта или объекта, представляющего что-то вроде человека. Затем я могу сериализовать человека с помощью DTO и отправить его клиенту. Если клиент изменяет объект, на нем может быть установлен флаг IsDirty, поэтому, когда он отправляется обратно на сервер, я знаю, чтобы обновить его.

Но что, если у меня есть объект Order? Он содержит основной заголовок информации, клиента, поставщика, требуемую дату и т. Д. Затем он имеет OrderItems, который представляет собой List , представляющий собой элементы, которые необходимо заказать. Я хочу иметь возможность использовать этот бизнес-объект в моем пользовательском интерфейсе. Итак, у меня есть несколько текстовых полей, связанных с местоположением, поставщиком, требуемой датой и т. Д., И сеткой, связанной с OrderItems. Поскольку OrderItems является списком, я могу легко добавлять и удалять записи в нем. Но как это отследить, особенно удаленные элементы. Я не хочу, чтобы удаленные элементы были видны в моей сетке, и я не должен иметь возможность перебирать их, если я использовал foreach, потому что они были удалены. Но мне все еще нужно отследить факт удаления. Как я могу отслеживать изменения. Я думаю, что мне нужно использовать единицу работы? Но тогда код кажется довольно сложным. Итак, я удивляюсь, почему бы просто не использовать DataTables и бесплатно отслеживать отслеживание изменений? Но потом я прочитал, как бизнес-объекты - это путь.

Я нашел различные примеры на простых примерах Person, но не примеры с подробными заголовками, такие как Orders.

Кстати, используя для этого C # 3.5.

Ответы [ 3 ]

6 голосов
/ 17 сентября 2008

Во-первых, вы можете использовать существующую платформу для решения этих проблем, например CSLA.NET. Автор этой структуры решил эти самые проблемы. Для этого перейдите на http://www.rockfordlhotka.net/cslanet/. Даже если вы не используете полную структуру, эти концепции все еще применимы.

Если вы хотите свернуть свои собственные, то, что я делал раньше, вместо использования List для моих коллекций, я использовал пользовательский тип, производный от BindingList. Inherting from BindingList позволяет вам переопределить поведение добавления / удаления элемента. Так, например, у вас может быть другая внутренняя коллекция «удаленных» элементов. Каждый раз, когда в вашей коллекции вызывается переопределенный метод Remove, помещайте элемент в «удаленную» коллекцию и вызывайте базовую реализацию метода Remove. Вы можете сделать то же самое для добавленных или измененных элементов.

2 голосов
/ 17 сентября 2008

Вы точно знаете, что вам нужна единица работы, но не пишите ее. Используйте NHibernate или какой-либо другой ORM. Вот для чего они созданы. У них есть встроенная единица работ.

Бизнес-объекты действительно являются «подходом» для большинства приложений. Вы погружаетесь в глубокую область, и вам предстоит многому научиться. Загляни в DDD.

Я бы также настоятельно рекомендовал не использовать подобный код в вашем коде. Посмотрите на шаблон MVP.

Я бы также (в то время как я пытался узнать много новых, очень важных вещей) заглянуть в SOLID.

Возможно, вы захотите проверить только курс JP Boodhoo .net, так как он охватывает многие из этих вещей.

0 голосов
/ 17 сентября 2008

Объекты данных не отслеживают изменения. Отслеживание изменений происходит в DataContext и объектах, которые вы получили через DataContext. Таким образом, чтобы отслеживать изменения, вам нужно сделать следующее:

public class FooDataContext : DataContext
{
   public Table<Order> Orders;   
}

public class Order
{
    [DbColumn(Identity = true)]
    [Column(DbType = "Int NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
    public int Id { get; set; }

    [DbColumn(Default = "(getutcdate())")]
    [Column(DbType = "DateTime", CanBeNull = false, IsDbGenerated = true)]
    public DateTime DateCreated { get; set; }

    [Column(DbType = "varchar(50)", CanBeNull = false, IsDbGenerated = false)]
    public string Name { get; set; }
}

Теперь в вашем коде вы можете сделать что-то вроде:

public void UpdateOrder(int id, string name)
{
   FooDataContext db = new FooDataContext();
   Order order = db.Orders.Where(o=>o.Id == id).FirstOrDefault();

   if (order == null) return;

   order.Name = name;

   db.SubmitChanges();
}

Я бы не рекомендовал напрямую использовать контекст данных в коде, но это хороший способ начать работу с Linq To SQL. Я бы порекомендовал поместить все ваши взаимодействия с базой данных во внешний проект и вызывать из GUI классы, которые инкапсулируют это поведение.

Я бы порекомендовал создать файл Linq To Sql (dbml), если вы новичок в Linq To Sql.

Щелкните правой кнопкой мыши свой проект в обозревателе решений и выберите Добавить новый элемент. Выберите файл Linq To SQL, и он позволит вам подключиться к базе данных и выбрать таблицы.

Затем вы можете посмотреть на сгенерированный код и получить отличные идеи о том, как работает Linq To Sql и что вы можете с ним сделать.

Используйте это как руководство по работе с Linq to SQL, и это унесет вас далеко ...

...