Давайте же подробно изучим, что произошло "за кулисами" в результате перетаскивания из Server Explorer в конструктор O/R Designer.
Во-первых, в файл app.config (или web.config) автоматически записывается строка подключения, которая необходима для того, чтобы открыть подключение к выбранной базе данных. Она будет использоваться LINQ для выполнения вызовов базы данных (по мере необходимости). Кроме того, был определен новый класс. Вот фрагмент класса Employee, в котором показан его конструктор:
public Employee()
{
this._Employees = new EntitySet<Employee>
(new Action<Employee>(this.attach_Employees), new Action<Employee>(this.detach_Employees));
this._Employeel = default(EntityRef<Employee>);
OnCreated() ;
}
Примечание
Визуальный конструктор O/R Designer автоматически приводит имена объектов к единственному числу. Например, во многих кадровых базах данных имеется таблица служащих с названием "employees", поскольку она содержит записи более чем об одном служащем. Для сокращения разночтений между объектной моделью и моделью данных конструктор O/R Designer создаст класс Employee (а не Employees). Это гораздо лучше соответствует смыслу класса (который должен содержать единственную строку таблицы, а не всю таблицу целиком).
Вы видите, что LINQ помечает объектную модель атрибутами для выполнения связывания объектов и базы данных: при помощи атрибута Table этот класс был идентифицирован как соответствующий таблице HumanResources.Employee.
Каждый столбец таблицы Employee был также реализован как свойство класса Employee. Следующий фрагмент показывает свойство Employee id:
[Column(Storage="_EmployeeID", AutoSync=AutoSync.Onlnsert,
DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] public int EmployeelD {
get
{
return this._EmployeeID;
}
set
{
if ((this._EmployeeID != value))
{
this.OnEmployeelDChanging(value);
this.SendPropertyChanging() ;
this._EmployeeID = value;
this.SendPropertyChanged("EmployeelD");
this.OnEployeelDChanged();
}
}
}
Кроме объекта Employee имеется также код, сгенерированный для контекста данных. Вот фрагмент определения класса, созданного для нас автоматически:
[System. Data.Linq.Mapping.DatabaseAttribute(Name="AdventureWorks")] public partial class DataClasseslDataContext : System.Data.Linq.DataContext {
private static System.Data.Linq.Mapping.MappingSource mappingSource =
new AttributeMappingSource();
#region Extensibility Method Definitions partial void OnCreated();
partial void InsertEmployee(Employee instance); partial void UpdateEmployee(Employee instance); partial void DeleteEmployee(Employee instance);
#endregion
public DataClasseslDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public System.Data.Linq.Table<Employee> Employees {
get
{
return this.GetTable<Employee>();
}
i
}
}
Вы можете представлять себе DataContext как менеджер LINQ: он обрабатывает подключение к базе данных, управляет находящимися в памяти объектами, маршалирует вызовы для обновлений данных, а также занимается всеми проблемами, которые могут возникнуть вследствие параллелизма и конфликтов блокировок. Для того чтобы все это работало, было сгенерировано более 500 строк кода. Итак, как же использовать объект LINQ внутри вашего приложения? Читайте дальше.