如何在LINQ C#中有效地选择导航属性

时间:2016-04-21 09:30:05

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

我有三张桌子

表#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:Emplyee

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 -> JobID是来自职位表外键BossEmp -> BossID, EmpID外键来自员工表

EDMX类图是

enter image description here

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<WorkInfo>,它应该只包含女性。

请帮助我如何在LINQ C#中有效地选择导航属性来构建List<WorkInfo>

数据库包含超过1000K的记录。

我尝试了以下代码:

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

2 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

以下是我根据您的课程快速为您准备的示例。

这应该从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集合后才执行,一次到DB并返回。

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

如果您运行SQL事件探查器,则可以自行验证。