《Entity Framework 6 Recipes》中文翻译——第十章EntityFramework存储过程处理(六)
在TPT继承模式中填充实体
问题
您希望使用存储过程来填充表中的实现TPT继承模式的实体。
解决方案
比方说,在这个模型中,实体杂志Magazine和光盘DVD扩展了基本实体媒体Media。在下面的数据库中,我们分别有一个表对应每个实体。我们已经已经使用了TPT继承模式实现了这些实体。我们希望使用存储过程从数据库中获取该模型的数据。
要创建和使用返回这些实体的存储过程,要做以下操作。
1、在您的数据库中,创建列表中存储的过程
create procedure [dbo].[GetAllMedia] as begin select m.MediaId,c.Title,m.PublicationDate, null PlayTime,'Magazine' MediaType from Media c join Magazine m on c.MediaId = m.MediaId union select d.MediaId,c.Title,null,d.PlayTime,'DVD' from Media c join DVD d on c.MediaId = d.MediaId end
2、右键单击设计面,并从数据库中选择更新模型。选择GetAllMedia存储过程。单击“完成”将存储过程添加到模型中。
3、右键单击设计图面上,并选择“添加➤函数导入。在“对话框”中,选择“GetAllMedia”存储过程。在函数导入名称文本框中“GetAllMedia”。选择实体作为集合的类型,并作为返回的实体类型的Media。单击“确定”。这将创建骨架<FunctionImportMapping>。
4、右键单击.edmx文件,并选择与➤XML编辑器打开。编辑函数导入映射框架中的映射部分<FunctionImportMapping >标签,将存储过程返回的行映射到该杂志Magazine 或基于媒体类型列的光盘DVD 实体上。
<FunctionImportMapping FunctionImportName="GetAllMedia" FunctionName="School5Model.Store.GetAllMedia"> <ResultMapping> <EntityTypeMapping TypeName="School5Model.Magazine"> <ScalarProperty ColumnName="PublicationDate" Name="PublicationDate"/> <Condition ColumnName="MediaType" Value="Magazine"/> </EntityTypeMapping> <EntityTypeMapping TypeName="School5Model.DVD"> <ScalarProperty ColumnName="PlayTime" Name="PlayTime"/> <Condition ColumnName="MediaType" Value="DVD"/> </EntityTypeMapping> </ResultMapping> </FunctionImportMapping>
5、下面开始调用存储过程
using (var context = new School5Entities()) { context.Medias.Add(new Magazine { Title = "Field and Stream", PublicationDate = DateTime.Parse("6/12/1945") }); context.Medias.Add(new Magazine { Title = "National Geographic", PublicationDate = DateTime.Parse("7/15/1976") }); context.Medias.Add(new DVD { Title = "Harmony Road", PlayTime = "2 hours, 30 minutes" }); context.SaveChanges(); } using (var context = new School5Entities()) { var allMedia = context.GetAllMedia(); Console.WriteLine("All Media"); Console.WriteLine("========="); foreach (var m in allMedia) { if (m is Magazine) Console.WriteLine("{0} Published: {1}", m.Title, ((Magazine)m).PublicationDate.ToShortDateString()); else if (m is DVD) Console.WriteLine("{0} Play Time: {1}", m.Title, ((DVD)m).PlayTime); } }
运行结果
解决该问题的两个关键部件为设置的存储过程的结果给鉴别器列和有条件的结果映射Magazine和DVD的实体。
鉴别器列元数据列指定的数据库记录表示的对象的类型。