【问题标题】:How to Select a Navigation Property efficiently in LINQ C#如何在 LINQ C# 中有效地选择导航属性
【发布时间】:2016-04-21 09:30:04
【问题描述】:

我有三张桌子

表 #1:BossEmp

SNo     JobID     BossID      EMPID       StartDt
_____________________________________________________
  1        1           6          1       05-20-2016
  2        1           6          2       05-20-2016
  3        2           7          3       06-20-2016
  4        2           7          4       06-20-2016
  5        2           7          5       06-20-2016

表 #2:员工

EmpID    EmpName      Gender    DOB           Dep
_________________________________________________________    
    1    Sakthivel     M        12-11-1986    Development
    2    Regina        F        04-03-1989    Development
    3    Samantha      F        12-12-1987    Development
    4    Keerthi       F        08-18-1988    Development
    5    Pranitha      F        11-10-1985    Development
    6    Vijay         M        02-21-1987    Development
    7    Bhavana       F        12-06-1985    Development

表#3:工作

JobID     Title            Description
__________________________________________
    1     RSI              Description RSI
    2     MSI              Description MSI

在表 #1 中,BossEMP -> JobIDJob Table 中的 外键BossEmp -> BossID, EmpID外键 strong>员工表。

EDMX 类图是

BossEmps -> EmpID === Employee -> EmpID
BossEmps1 -> BossID === Employee -> EmpID

BossEmps -> JobID === Job -> JobID

现在我需要创建一个模型的对象

Class WorkInfo
{
    public List<Employee> EmpList { get; set; }
    public Job JobInfo { get; set; }
}

现在我需要创建List&lt;WorkInfo&gt;,它应该只包含女性。

请帮助我如何在 LINQ C# 中有效地选择导航属性来构造List&lt;WorkInfo&gt;

数据库包含超过 100 万条记录。

我尝试了以下代码:

using (var db = new EmployeeEntities()) {
                db.BossEmps.Where(b => b.Employee.Gender == "F").Select(e => new {
                    Emp = new {
                        Name = e.Employee.EmpName,
                        Id = e.Employee.EmpId
                    },
                    JobInfo = new {
                        Name = e.Job.Title,
                        Id = e.Job.JobID
                    }
                }).GroupBy(x => x.JobInfo).ToList();
            }

【问题讨论】:

  • 你想要一个包含 List 的 List 吗?这听起来不对。你试过什么了?有什么代码不能按你的意愿工作吗?
  • 等一下,我会追加...
  • WorkInfo 中的 List() 应该只是 Employee 的单个实例,因为您将包含多个 WorkInfo 对象,您可以将它们放入 List
  • @monstertjie_za WorkInfo 表示工作,现在我有两个工作,所以我使用 List
  • 请包括所涉及的实体模型类(例如Employee、Job等)。最后,您尝试过的 LINQ 查询速度很慢,因此我们可以对其进行分析并建议您使用更好的查询(如果有的话)。

标签: c# linq linq-to-entities edmx navigation-properties


【解决方案1】:

如果我猜对了,你需要所有从事相同工作的女性员工。 在这种情况下,我认为您正在寻找这样的东西:

var workInfo = context.BossEmp.Select(b => new
        {
            EmpList = b.Employes.Where(e => b.EmployeId == e.EmployeId && e.Gendar.Equals("F")),
            Job = b.Jobs.FirstOrDefault(j => b.JobId == j.JobId)
        });

这将创建具有 EmpList 和 Job 属性的对象集合。如果你需要它作为 List,你可以使用 ToList() 方法。

var employees = workInfo.EmpList.ToList();

和/或

var workInfos = workInfo.toList();

【讨论】:

  • 消除问题 tanx
【解决方案2】:

这是我根据您的课程快速为您整理的示例。

这应该从 BossEmp 集合中选择所有女性及其相应的工作信息和员工信息。

public class Program
{
    public static void Main(string[] args)
    {
        Program p = new Program();
    }

    public Program()
    {
        var bossEmpCollection = new List<BossEmp>()
        {
            new BossEmp() { SNo = 2, JobID = 1, BossID = 6, EmpID = 2, StartDt = DateTime.Now },
            new BossEmp() { SNo = 1, JobID = 1, BossID = 6, EmpID =  1, StartDt = DateTime.Now }
        };
        var employeeCollection = new List<Employee>()
        {
            new Employee() { EmpID = 1, EmpName = "Sakthivel", Gender = 'M', DOB = DateTime.Now, Dep = "Development" },
            new Employee() { EmpID = 2, EmpName = "Regina", Gender = 'F', DOB = DateTime.Now, Dep = "Development" }
        };
        var jobCollection = new List<Job>()
        {
            new Job() { JobID = 1, Title = "RSI", Description = "RSI" }
        };

        var workInfoCollection = from bEmp in bossEmpCollection
                                 join e in employeeCollection on bEmp.EmpID equals e.EmpID
                                 join j in jobCollection on bEmp.JobID equals j.JobID
                                 where e.Gender.Equals('F')
                                 select new WorkInfo() { EmpObject = e, JobInfo = j };

        foreach (var workInfo in workInfoCollection)
        {
            Console.WriteLine($"Emp Name: {workInfo.EmpObject.EmpName} Work Desc: {workInfo.JobInfo.Description}");
        }

        Console.ReadKey();
    }
}
public class BossEmp
{
    public int SNo { get; set; }
    public int JobID { get; set; }
    public int BossID { get; set; }
    public int EmpID { get; set; }
    public DateTime StartDt { get; set; }
}
public class WorkInfo
{
    public Employee EmpObject { get; set; }
    public Job JobInfo { get; set; }
}

public class Employee
{
    public int EmpID { get; set; }
    public string EmpName { get; set; }
    public char Gender { get; set; }
    public DateTime DOB { get; set; }
    public string Dep { get; set; }

}
public class Job
{
    public int JobID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
}

使用此示例,将把 LINQ 构造成一个 SQL SELECT 语句,并且仅在您循环遍历 workInfoCollection 集合后执行,一次往返于数据库并返回。

每次您访问模型类上的导航属性时,后台的延迟执行都会与数据库建立连接,并且只针对您想要查看的特定项目运行查询,基本上,在我看来,调用数据库会降低效率。

如果您运行 SQL 分析器,您将能够自己验证这一点。

【讨论】:

  • 如果我使用了 JOIN 意味着没有使用导航属性。请使用导航属性而不是 JOINS。
  • 您指的是延迟执行发生的实体框架导航属性吗?你在使用实体框架吗?
  • 请给出与导航属性相关的答案。
  • 不太清楚我对导航属性的回答是什么意思?
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 2016-06-05
  • 2016-06-30
  • 2017-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
相关资源
最近更新 更多