• Entity Framework 6 Recipes 2nd Edition(11-4)译 -> 在”模型定义”函数里调用另一个”模型定义”函数


    11-4.在”模型定义”函数里调用另一个”模型定义”函数

    问题

    想要用一个”模型定义”函数去实现另一个”模型定义”函数

    解决方案

    假设我们已有一个公司合伙人关系连同它们的结构模型,如Figure 11-4所示:

     

    Figure 11-4. A model representing the associate types in a company together with the reporting association

    在我们的虚拟的公司里, , team members被一个team leader管理. Team leaders 被 project Managers管理. 而Supervisors管理 project managers.

    如果我们想从给定的一个project manager 或supervisor返回所有他们管理的team members ,我们将需要通过  project managers 和team leaders才能获取到 team members. 为了隐藏导航透过这些层的复杂性,我们可以创建”模型定义”函数,来更简单地和直接地访问这些导航属性:

    1. 在解决方案资源管理中右击.edmx 文件,打开方式 ➤ XML 编辑器.

    2.把Listing 11-7 里的代码插入到概念层的<Schema> 标签下,这样就定义好了函数

    Listing 11-7. Model-Defined Functions for Navigating the Associate Hierarchy

        <Function Name="GetProjectManager" ReturnType="EFRecipesModel1104.ProjectManager">

              <Parameter Name="teammember" Type="EFRecipesModel1104.TeamMember" />

              <DefiningExpression>

                treat(teammember.Manager.Manager as EFRecipesModel1104.ProjectManager)

              </DefiningExpression>

            </Function>

            <Function Name="GetSupervisor" ReturnType="EFRecipesModel1104.Supervisor">

              <Parameter Name="teammember" Type="EFRecipesModel1104.TeamMember" />

              <DefiningExpression>

                treat(EFRecipesModel1104.GetProjectManager(teammember).Manager as

                EFRecipesModel1104.Supervisor)

              </DefiningExpression>

            </Function>

    3.插入和查询模型的代码,如 Listing 11-8所示:

    Listing 11-8. Using Both eSQL and LINQ to Query the Model

        class Program

        {

            static void Main(string[] args)

            {

                RunExample();

     

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

                Console.ReadKey();

            }

            static void RunExample()

            {

                using (var context = new EFRecipesEntities1104())

                {

                    context.Database.ExecuteSqlCommand("delete from chapter11.associate");

                    var john = new Supervisor { Name = "John Smith" };

                    var steve = new Supervisor { Name = "Steve Johnson" };

                    var jill = new ProjectManager

                    {

                        Name = "Jill Masterson",

                        Manager = john

                    };

                    var karen = new ProjectManager

                    {

                        Name = "Karen Carns",

                        Manager = steve

                    };

                    var bob = new TeamLead { Name = "Bob Richardson", Manager = karen };

                    var tom = new TeamLead { Name = "Tom Landers", Manager = jill };

                    var nancy = new TeamMember { Name = "Nancy Jones", Manager = tom };

                    var stacy = new TeamMember

                    {

                        Name = "Stacy Rutgers",

                        Manager = bob

                    };

     

                    context.Associates.Add(john);

                    context.Associates.Add(steve);

                    context.SaveChanges();

                }

                using (var context = new EFRecipesEntities1104())

                {

                    Console.WriteLine("Using eSQL...");

                    var emps = context.Associates.OfType<TeamMember>()

                        //译注:这个where是下载的源码用的形式,但它怎么看也不是eSQL

                            .Where(q => q.Manager.Name == "Jill Masterson" || q.Manager.Name == "Steve Johnson");

                    //译注:这个where里书里的代码,倒像eSQL,可是找不到Where这个形式的重载,可能在某个扩展包里,有知晓,望赐教!

                    //                .Where(@"EFRecipesModel1104.GetProjectManager(it).Name = @projectManager ||

                    //EFRecipesModel.GetSupervisor(it).Name == @supervisor",

                    //                new ObjectParameter("projectManager", "Jill Masterson"),

                    //                new ObjectParameter("supervisor", "Steve Johnson"));

                    Console.WriteLine("Team members that report up to either");

                    Console.WriteLine("Project Manager Jill Masterson ");

                    Console.WriteLine("or Supervisor Steve Johnson");

                    foreach (var emp in emps)

                    {

                        Console.WriteLine(" Associate: {0}", emp.Name);

                    }

                }

                using (var context = new EFRecipesEntities1104())

                {

                    Console.WriteLine();

                    Console.WriteLine("Using LINQ...");

                    var emps = from e in context.Associates.OfType<TeamMember>()

                               where MyFunctions.GetProjectManager(e).Name ==

                               "Jill Masterson" ||

                               MyFunctions.GetSupervisor(e).Name == "Steve Johnson"

                               select e;

                    Console.WriteLine("Team members that report up to either");

                    Console.WriteLine("Project Manager Jill Masterson ");

                    Console.WriteLine("or Supervisor Steve Johnson");

                    foreach (var emp in emps)

                    {

                        Console.WriteLine(" Associate: {0}", emp.Name);

                    }

                }

            }

        }

        public class MyFunctions

        {

            [EdmFunction("EFRecipesModel1104", "GetProjectManager")]

            public static ProjectManager GetProjectManager(TeamMember member)

            {

                throw new NotSupportedException("Direct calls not supported.");

            }

     

            [EdmFunction("EFRecipesModel1104", "GetSupervisor")]

            public static Supervisor GetSupervisor(TeamMember member)

            {

                throw new NotSupportedException("Direct calls not supported.");

            }

    }

    上述Listing 11-8 代码输出如下:

    Using eSQL...

    Team members that report up to either

    Project Manager Jill Masterson

    or Supervisor Steve Johnson

    Associate: Nancy Jones

    Associate: Stacy Rutgers

     

    Using LINQ...

    Team members that report up to either

    Project Manager Jill Masterson

    or Supervisor Steve Johnson

    Associate: Nancy Jones

    Associate: Stacy Rutgers

    它是如何工作的?

    在如Listing 11-7所示的GetSupervisor() 函数中,我们需要做给 Manager 属性做三次导航.第一次从TeamMember导航到TeamLead, 第二次从TeamLead,导航到ProjectManager,最后一次从ProjectManager导航到Supervisor. 在Listing 11-7中,我们也定义了GetProjectManager() 函数,所以我们可以用这个函数来简化GetSupervisor() 函数.

    我们使用eSQL的treat()运算符把一个公司合伙人实例转化为它们正确的类型 (ProjectManager 或Supervisor). 如果不使用这个运算符,EF将引发一个异常(不能遇到将Associate 映射为ProjectManager 或Supervisor)

    在Listing 11-8中, 用 GetProjectManager() 和GetSupervisor() 函数,可以使我们的代码简洁些,因为隐藏了所有通过Manager导航属性穿越对象图的细节

    因为我们函数不是返回一个IQueryable<T>, 所以我们不必为LINQ查询实现运行时方法,只需要用到它们的方法存根.

     

    附:创建示例用到的数据库的脚本文件

  • 相关阅读:
    [LeetCode-JAVA] Count Complete Tree Nodes
    [LeetCode-JAVA] Shortest Palindrome
    [LeetCode-JAVA] Best Time to Buy and Sell Stock IV
    [LeetCode-JAVA] Word Ladder II
    [LeetCode-JAVA] Jump Game II
    Keil开发的ARM程序main函数之前的汇编分析
    STM32平台SD卡的FatFS文件系统开发
    STM32 Cortex-M3 NMI异常
    应对STM32 Cortex-M3 Hard Fault异常
    LwIP协议栈开发嵌入式网络的三种方法分析
  • 原文地址:https://www.cnblogs.com/kid1412/p/5156315.html
Copyright © 2020-2023  润新知