EF學習筆記-2 EF之支持復雜類型的實現
使用過.NET的小夥伴們知道,在我們的實體模型中,除了一些簡單模型外,還有一些復雜類型,如幾個簡單的類型組合而成的類型;而EF除了在實現基本的增刪改查之外,也支持復雜類型的實現。
那麽如何手動構造復雜類型(ComplexType)
以及復雜類型的簡單動作呢?一般比如:一張用戶表User,其中有兩個字段FirstName和LastName,那麽對應的User實體類將會FirstName和LastName兩個屬性。如果我們想把FirstName和LastName合成一個UserName屬性時,並且想要在EF中實現這個想法,我們就需要用到復雜類型。
目前,由於EF不能顯示支持復雜類型,所以我們也無法在VS中的可視化設計器中設計該復雜類型,所以我們只能暫時手動修改實體類型,以便可以支持復雜類型的屬性。有如下幾個步驟:
產生實體模型
修改CSDL文件
修改MSL文件
重新生成模型實體類
在後續的介紹中,我會針對User表對應的實體類來增加復雜屬性TelePhone,其中復雜屬性TelePhone由Tel,NickName,Emal組成。
一、產生實體模型
實體模型我們可以使用VS自帶的可視化設計器來實現。了解過EF的基礎的朋友應該知道這個設計,具體步驟這裏就復述了。我產生的實體模型UserInfoEntity.edmx。
二、修改CSDL文件
產生實體文件後,我們可以使用Notepad++打開實體模型,找到實體模型中關於CSDL定義的部分,然後找到實體類型名為Users的定義節,刪除原來的Tel,NickName,Emal屬性定義,增加一個名為TelePhone的屬性節點。代碼如下所示:
<EntityType Name="Users"> <Key> <PropertyRef Name="UsersID" /> </Key> <Property Name="UserID" Type="String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true" /> <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" /> <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" /> <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" /> <Property Name="Address" Type="NorthwindModel.CommonAddress" Nullable="false"></Property> <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" /> <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" /> <NavigationProperty Name="Orders" Relationship="NorthwindModel.FK_Orders_Customers" FromRole="Customers" ToRole="Orders" /> <NavigationProperty Name="CustomerDemographics" Relationship="NorthwindModel.CustomerCustomerDemo" FromRole="Customers" ToRole="CustomerDemographics" /> </EntityType>
接著,需要添加一個名為CommonTelePhone
復雜類型的定義,具體代碼如下
<ComplexType Name="CommonTelePhone">
<Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
<Property Name="NickName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
<Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="Emal" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
<Property Name="Tel" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
</ComplexType>
到此,CSDL的修改部分已完畢。
三、MSL文件
找到MSL部分的定義,修改Users部分的影射定義。代碼如下所示(請註意ComplexProperty 節
):
<EntitySetMapping Name="Users">
<EntityTypeMapping TypeName="IsTypeOf(NorthwindModel.Customers)">
<MappingFragment StoreEntitySet="Customers">
<ScalarProperty Name="UserID" ColumnName="CustomerID" />
<ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
<ScalarProperty Name="ContactName" ColumnName="ContactName" />
<ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
<ComplexProperty Name="Address" TypeName="NorthwindModel.CommonAddress">
<ScalarProperty Name="Address" ColumnName="Address" />
<ScalarProperty Name="NickName" ColumnName="NickName" />
<ScalarProperty Name="Region" ColumnName="Region" />
<ScalarProperty Name="Emal" ColumnName="Emal" />
<ScalarProperty Name="Tel" ColumnName="Tel" />
</ComplexProperty>
<ScalarProperty Name="Phone" ColumnName="Phone" />
<ScalarProperty Name="Fax" ColumnName="Fax" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
到此,MSL的修改部分已完畢。
四、重新產生實體類文件
我們可以使用EmdGen2
工具來重新生成實體類.cs的文件。對於EmdGen2
工具的使用方法就不在這裏介紹了。具體可百度或者查看我之後關於EmdGen2
工具的使用方法的博客。那麽這裏的具體操作就是如下所示。
將修改好的模型文件(edmx),拷貝到emdgen2.exe目錄下,然後在命令行中輸入:Emdgen2 /codegen cs NorthwindEnites.edmx。執行此命令後,會在當前文件夾中生成一個NorthwindEnites.cs的文件,也就是實體類的代碼文件。接著將文件名改成:NorthwindEnites.Designer.cs
,這一步驟主要是和edmx對應起來。
最後,將 NorthwindEnites.edmx 和NorthwindEnites.Designer.cs 文件添加到項目中。
至此,復合類型的修改完畢。
按照上述操作步驟,我們可以給Employess也增加一個Address 的復雜類型屬性。
接下來,我們看看具體使用代碼:
查詢
public void TestAddress()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
Console.WriteLine("Get first users addresss :");
var cts = db.Customers.Take(5);
foreach (var c in cts)
{
Console.WriteLine("Address:{0},Tel:{1},NickName:{2},Emal:{3}",
c.Address.Address, c.Address.Tel, c.Address.NickName, c.Address.Emal);
}
Console.WriteLine("Get first Employess address:");
var emp = db.Customers.Take(5);
foreach (var c in emp)
{
Console.WriteLine("Address:{0},Tel:{1},NickName:{2},Emal:{3}",
c.Address.Address, c.Address.Tel, c.Address.NickName, c.Address.Emal);
}
}
}
添加
public void AddTest()
{
using (var db = new NorthwindModel.NorthwindEntities1())
{
var customer = new NorthwindModel.Customers
{
UserID = "340956",
CompanyName = "JinShan Company",
ContactName = "xray2017",
Address = new NorthwindModel.CommonAddress
{
Address = "WuHan,China",
NickName = "AiXiaoJun",
Tel = "15290896766",
Emal = "[email protected]",
Region = "LiuHeng"
}
};
db.AddToCustomers(customer);
db.SaveChanges();
var cst = db.Customers.FirstOrDefault(c => c.CustomerID == "2009");
Assert.IsNotNull(cst);
Console.WriteLine("UserID:{0},CompanyName:{1},ContactName:{2},NickName:{3},Tel:{4}",
cst.UserID, cst.CompanyName, cst.ContactName, cst.Address.NickName, cst.Address.Tel);
}
}
有不對的地方請各位批評指正,互相學習!
EF學習筆記-2 EF之支持復雜類型的實現