Инициализация объекта Linq to Sql через бизнес-логику - PullRequest
2 голосов
/ 27 марта 2009

Я хотел бы расширить класс, сгенерированный Linq To Sql, для инициализации при создании нового объекта (= строки).

Я хочу добавить строки в дочернюю таблицу при создании родительской строки.

Я надеялся использовать метод Oncreated (частично) сделать что-то вроде этого:

partial class Product {
    partial void OnCreated() {
        // Fill default rows for FK relations
        this.Columns.Add(new ProductColumn {
            Name = "Name", ColumnType = 1
        });
        this.Columns.Add(new ProductColumn {
            Name = "Producer", ColumnType = 2
        });
    }
}

OnCreated вызывается каждый раз из конструктора. То же самое, если объект будет загружен из базы данных после вызова OnCreated. И если объект загружен из базы данных, не хотите выполнять код.

Так, где я могу добавить логику в мою модель для инициализации объекта (-graph)?

Ответы [ 4 ]

3 голосов
/ 31 марта 2009

В сгенерированных классах Linq to SQL нет встроенного метода для этого. Они вызывают OnLoaded специально при вызове из БД, но они ничего не вызывают, когда это не так. Я подозреваю, потому что нет способа узнать наверняка ...

Я бы рекомендовал использовать заводской подход, предложенный Крисом.

2 голосов
/ 31 марта 2009

С LINQ-to-SQL сущности в значительной степени не знают о родительском контексте данных - об этом подробно знают только лениво загруженные члены, такие как EntitySet<T>. Вы можете идентифицировать наборы сущностей с учетом контекста данных, взглянув на .IsDeferred (при условии, что является отложенным) - это будет верно, если задействован контекст данных, и false в противном случае - но есть и другие проблемы :

  • LINQ-to-SQL присоединяет контекст данных (для отложенного выполнения) после , с помощью которого constructur (и OnCreated) выполнил
  • Если вы добавляете элементы вручную в OnCreated / .ctor(), происходит сбой, когда LINQ-to-SQL пытается присоединить контекст данных
  • LINQ-to-SQL использует конструктор по умолчанию, это означает, что generics / new() и т. Д. Также будут использовать этот код

Так что, к сожалению; нет, я не думаю, что вы можете сделать это в OnCreated любым разумным способом. Вы могли бы:

  • есть второй конструктор для этого использования, который добавляет дополнительные элементы
  • использовать фабричный метод, то есть статический .Create() метод, который правильно строит элементы

(поскольку LINQ-to-SQL не будет использовать ни один из вышеперечисленных)

1 голос
/ 30 марта 2009

Я думаю, в этом случае вам лучше использовать Factory для создания ваших экземпляров; Так что везде, где у вас есть текущий код:

Product p = new Product();

Вместо этого вы бы получили:

Product p = ProductFactory.CreateProduct();

И ваш метод CreateProduct () будет выглядеть примерно так:

public Product CreateProduct()
{
    var p = new Product();
    p.Columns.Add(new ProductColumn {
        Name = "Name", ColumnType = 1
    });
    p.Columns.Add(new ProductColumn {
        Name = "Producer", ColumnType = 2
    });
    return p;
}
0 голосов
/ 27 марта 2009

Если вы используете дизайнер - и я полагаю, что вы используете частичные классы - вы можете добавить ассоциацию в дизайнер, и соответствующие столбцы будут добавлены к вашему объекту автоматически. В MSDN есть ссылка на , как создавать ассоциации с использованием рабочей поверхности дизайнера.

...