Entity Data Model是.NET Framework v3.5 SP1引入的新功能,比Linq To SQL更加強大的ORM,讓開發人員只需要著眼於領域對象模型的開發,而不需要考慮它們是如何與關系數據庫交互。本系列文章逐步深入介紹如下內容:EDMX Schema 文件、Model Browser、映射關系、產生的實體類(Generated entity classes)、文檔(Documentation)等等。
1. EDMX Schema 文件
可以將EDMX作為XML文件打開,你會發現該文件包含3個主要部分。
Conceptual Models (CSDL)
Storage Models (SSDL)
Mapping (MSL)
一般情況下,你沒有必要手動修改EDMX -XML文件。可視化的EDM 設計器、Mapping Details窗口和Model Browser 窗口包含有上述3個部分,並非常友好地顯示整個Entity Data Model模型。
當你編譯項目時,MSBuild 將從EDMX文件提取CSDL/SSDL/MSL內容,並放置3個獨立的XML文件到項目的輸出目錄。
2. Model Browser 窗口
Model Browser窗口以可視的樹形圖顯示概念模型和存儲模型。
3. Mapping details 窗口
EDM設計器也提供了一個不錯的Mapping Details 窗口,包含2個視圖。
Map Entity to Tables / View
這一視圖顯示了數據庫中所有字段和相應實體中的屬性,可以用來查看和編輯EDM的映射關系。
Map Entity to Functions
這一視圖用來選擇一個特定的存儲過程來插入、更新或刪除Entity實例。
4. 生成的實體類(Generated Entity Classes)
除了上述的XML Schema文件外,EDM向導也生成了實體類。下一步仔細分析.Designer.cs文件中的實體類,並和LINQ to SQL中的類進行比較。
1) 比較 LINQ to SQL class 和 EDM EntityObject class
// LINQ to SQL
[Table(Name="dbo.Employees")]
public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged
EDM類則是以不同的attributes,並且總是繼承EntityObject或ComplexObject 類。EntityObject 類提供了變更跟蹤和關系管理。
// Entity Data Model
[global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Employee")]
[global::System.Runtime.Serialization.DataContractAttribute()]
[global::System.Serializable()]
public partial class Employee : global::System.Data.Objects.DataClasses.EntityObject
2) 比較LINQ to SQL entity constructor 和 EDM Create method
// LINQ to SQL
public Employee()
{
this._Employees = new EntitySet<Employee>(new Action<Employee>(this.attach_Employees), new Action<Employee>(this.detach_Employees));
this._EmployeeTerritories = new EntitySet<EmployeeTerritory>(new Action<EmployeeTerritory>(this.attach_EmployeeTerritories),
new Action<EmployeeTerritory>(this.detach_EmployeeTerritories));
this._Orders = new EntitySet<Order>(new Action<Order>(this.attach_Orders), new Action<Order>(this.detach_Orders));
this._Employee1 = default(EntityRef<Employee>);
OnCreated();
}
EDM沒有生成上述LINQ to SQL的構造函數,而是創建了一個特定的Create方法,並提供了所有必需屬性(not nullable)的輸入參數。
// Entity Data Model
public static Employee CreateEmployee(int employeeID, string lastName, string firstName)
{
Employee employee = new Employee();
employee.EmployeeID = employeeID;
employee.LastName = lastName;
employee.FirstName = firstName;
return employee;
}
3) 比較LINQ to SQL 和 EDM : 實體屬性(entity property)
// LINQ to SQL
[Column(Storage="_EmployeeID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int EmployeeID
{
get
{
return this._EmployeeID;
}
set
{
if ((this._EmployeeID != value))
{
this.OnEmployeeIDChanging(value);
this.SendPropertyChanging();
this._EmployeeID = value;
this.SendPropertyChanged("EmployeeID");
this.OnEmployeeIDChanged();
}
}
}
盡管EDM公有屬性(public property)的attribute是不同的,但get和set 基本是一樣的。
// Entity Data Model
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public int EmployeeID
{
get
{
return this._EmployeeID;
}
set
{
this.OnEmployeeIDChanging(value);
this.ReportPropertyChanging("EmployeeID");
this._EmployeeID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
this.ReportPropertyChanged("EmployeeID");
this.OnEmployeeIDChanged();
}
}
4) 比較LINQ to SQL Table 和 EDM ObjectQuery
// LINQ to SQL
public System.Data.Linq.Table<Employee> Employees
{
get
{
return this.GetTable<Employee>();
}
}
在LINQ to SQL中,調用GetTable 方法,返回實體集合。在EDM中,通過Object Services compoment 執行Entity SQL 查詢,返回EntityType的計劃EntitySet。
// Entity Data Model
[global::System.ComponentModel.BrowsableAttribute(false)]
public global::System.Data.Objects.ObjectQuery<Employee> Employees
{
get
{
if ((this._Employees == null))
{
this._Employees = base.CreateQuery<Employee>("[Employees]");
}
return this._Employees;
}
}
private global::System.Data.Objects.ObjectQuery<Employee> _Employees;
5) 比較LINQ to SQL DataContext 和 EDM ObjectContext
// LINQ to SQL
[System.Data.Linq.Mapping.DatabaseAttribute(Name="Northwind")]
public partial class NorthwindDataContext : System.Data.Linq.DataContext
EDM有一個類似於LINQ to SQL DataContext 的ObjectContext類,ObjectContext 類是負責與EDM 中實體類型交互的基本類。ObjectContext用來創建數據庫連接、檢索數據、持久化對象、以及對數據庫的插入、更新和刪除操作。
// Entity Data Model
public partial class NorthwindEntities : global::System.Data.Objects.ObjectContext
ObjectContext的連接字符串指向元數據(CSDL/SSDL/MSL 文件)和數據源(數據庫連接字符串)。
connectionString="metadata=.\NorthwindModel.csdl|.\NorthwindModel.ssdl|.\NorthwindModel.msl;
provider=System.Data.SqlClient;provider connection string="
Data Source=SQLEXPRESS; Initial Catalog=Northwind; Integrated Security=True; MultipleActiveResultSets=True""
5. Documentation 屬性
EDM中的實體類型(EntityTypes)、關聯和屬性有一個Documentation屬性,對LINQ to SQL而言,這是一個新的屬性。
Documentation屬性將更新生成的partial實體類的XML注釋,可以用來生成代碼文檔的幫助文件。
/// <summary>
/// Employee entity which corresponds with the Northwind.Employees table
/// </summary>
/// <KeyProperties>
/// EmployeeID
/// </KeyProperties>
[global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Employee")]
[global::System.Runtime.Serialization.DataContractAttribute()]
[global::System.Serializable()]
public partial class Employee : global::System.Data.Objects.DataClasses.EntityObject
英文鏈接:
1. ADO.NET Entity Framework & LINQ to Entities,
http://www.scip.be/index.php?Page=ArticlesNET12