• Entity Framework 6 Recipes 2nd Edition(10-6)译 -> TPT继承模型中使用存储过程


    10-6. TPT继承模型中使用存储过程

    问题

    想在一个TPT继承模型中使用存储过程

    解决方案

    假设已有如Figure 10-6所示模型. 在模型里, Magazine(杂志) and DVD继承于基类Media(媒体,译注:示例数据库中的表名其实为:Medium,你在做例子或是下文代码出现Medium,请自己辨别). 在数据库里,每个实体各自有一个表,我们用TPT方式为为些表建模.我们想用一个存储过程从数据库中为这些模型来获取数据。

     

    Figure 10-6. A model using Table per Type inheritance. The model represents some information about magazines and DVDs

    ===================================================================

    ■■提示:如果需要复习TPT模式和它的性能影响?请查阅第2章的2-8小节

    ========================================================================================

    接下来创建存储过程及使用它获取实体

    1.在数据库中创建如 Listing 10-15所示的存储过程.

    Listing 10-15. The GetAllMedia Stored Procedure That Returns a Rowset with a Discriminator Column

    create procedure [Chapter10].[GetAllMedia]

    as

    begin

    select m.MediaId,c.Title,m.PublicationDate, null PlayTime,'Magazine' MediaType

    from chapter10.Media c join chapter10.Magazine m on c.MediaId = m.MediaId

    union

    select d.MediaId,c.Title,null,d.PlayTime,'DVD'

    from chapter10.Media c join chapter10.DVD d on c.MediaId = d.MediaId

    end

    2.右击模型设计视图,选择 “从数据库中更新模型”,选择存储过程GetAllMedia.点击“完成”

    3. ( 译注:我的环境是win10+vs2013+ef6.1.3,是不需要这步的,第1步已经把这步也完成了,只是最后的“返回以下内容的集合”必须修改一下)右击模型的设计视图, 选择“新增“ ➤ 函数导入. 从“存储过程/函数名称”下拉框中选择GetAllMedia. 在“函数导入名称“文本框中输入:GetAllMedia. 这个就是在模型中的方法名称.在“返回以下内容的集合”里勾选“实体”,在下拉框里选择Media.单击“确定”.将会创建<FunctionImportMapping>框架.

    4. 右击 .edmx 文件, 选择“打开方式” ➤ XML Editor.编辑.edmx文件的mapping 小节下

    的<FunctionImportMapping> 标签,用 Listing 10-16所示代码去匹配(因为像EF6RecipesModel的命名与你的例子可能不同).它会映射被存储过程返回的列与Media类型的实体的属性。

    Listing 10-16. This FunctionImportMapping Conditionally Maps the Returned Rows to Either the

    Magazine or the DVD Entity.

    <FunctionImportMapping FunctionImportName="GetAllMedia" FunctionName="EF6RecipesModel.Store.GetAllMedia">

    <ResultMapping>

    <EntityTypeMapping TypeName="EF6RecipesModel.Magazine">

    <ScalarProperty ColumnName="PublicationDate" Name="PublicationDate"/>

    <Condition ColumnName="MediaType" Value="Magazine"/>

    </EntityTypeMapping>

    <EntityTypeMapping TypeName="EF6RecipesModel.DVD">

    <ScalarProperty ColumnName="PlayTime" Name="PlayTime"/>

    <Condition ColumnName="MediaType" Value="DVD"/>

    </EntityTypeMapping>

    </ResultMapping>

    </FunctionImportMapping>

    5. 接下来用Listing 10-17所示的代码通过GetAllMedia()方法调用存储过程GetAllMedia

    Listing 10-17. Using the GetAllMedia Stored Procedure via the GetAllMedia() Method

        static void Main(string[] args)

            {

                using (var context = new EFRecipesEntities1006())

                {

                    context.Media.Add(new Magazine

                    {

                        Title = "Field and Stream",

                        PublicationDate = DateTime.Parse("6/12/1945")

                    });

                    context.Media.Add(new Magazine

                    {

                        Title = "National Geographic",

                        PublicationDate = DateTime.Parse("7/15/1976")

                    });

                    context.Media.Add(new DVD

                    {

                        Title = "Harmony Road",

                        PlayTime = "2 hours, 30 minutes"

                    });

                    context.SaveChanges();

                }

                using (var context = new EFRecipesEntities1006())

                {

                    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);

                    }

                }

                Console.WriteLine(" press any key to exit...");

                Console.ReadKey();

            }

    输出结果如下面的Listing 10-17:

    ===================================================================

    All Media

    =========

    Field and Stream Published: 6/12/1945

    National Geographic Published: 7/15/1976

    Harmony Road Play Time: 2 hours, 30 minutes

    ===========================================

    它是如何工作的?

    该解决方案有两个关键点:鉴别列注入到结果集中和用条件映射结果实体.

    ===================================================================

    ■■注意:鉴别列是用来指定对象类型的数据库元数据列的记录.

    ========================================================================================

    10-15所示的存储过程是把从 Magazine and取得的记录与从 DVD表取得的记录联合起来的表,然后把这个表注入到Magazine或DVD等媒体类型的鉴别列中.我们为每个select,我们都连接表示模型基类的 Media 表, 为了包含Title 列. 所有从这三个表来的记录,都包含在结果集中,并且含有具体从某个表来的标记.根据记录的标记(Magazine或DVD),我们把它们分别映射到Magazine 或DVD 实体. 这个操作在<FunctionImportMapping>节里完成,.

    当我们添加函数导入时添加了调用GetAllMedia存储过程的方法GetAllMedia(),在Listing 10-17里,我们调用该方法.之后,整个对象图被继承结构完整地实例化。我们遍历这个对象集合,交替得打印出Magazine 和DVD 实体.

  • 相关阅读:
    iis WebSocket 搭建环境及配置
    RESTful API 设计最佳实践
    laravel/lumen 单元测试
    后台管理UI的选择
    lumen Response
    计算机网络——OSI、TCP/IP协议族详解
    Java中'&'与、'|'或、'^'异或、'<<'左移位、'>>'右移位
    Servlet、Struts2、SpringMVC执行流程
    final修饰符,finally,finalize区别
    JSP的九个隐式(内置)对象
  • 原文地址:https://www.cnblogs.com/kid1412/p/5149404.html
Copyright © 2020-2023  润新知