Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用linq将表连接到类中的对象列表中_C#_Linq - Fatal编程技术网

C# 使用linq将表连接到类中的对象列表中

C# 使用linq将表连接到类中的对象列表中,c#,linq,C#,Linq,我必须在SQL数据库中创建表,并希望将其与linq连接起来。我用短小精悍的方式进入列表 如何使用linq连接这两个表 var persons = new List<Persons>(); var skills = new List<Skills>(); public class Skill { public int PerID { get; set; } public int SkillID { get;

我必须在SQL数据库中创建表,并希望将其与linq连接起来。我用短小精悍的方式进入列表

如何使用linq连接这两个表

    var persons = new List<Persons>();
    var skills = new List<Skills>();

    public class Skill
    {
        public int PerID { get; set; }
        public int SkillID { get; set; }
        public string SkillName { get; set; }
        public DateTime SkillValidTo { get; set; }
    }

    public class Persons
    {
        public int PerID { get; set; }
        public string PerName { get; set; }
        public List<Skill> PerSkills { get; set; }
    }
试试这个:

persons = from per in personen
              join sk in skills on per.PerID equals sk.PerID
              select new Persons()
              {
                  PerID = per.PerID,
                  PerName = per.PerName,
                  PerSkills = per.Skills 
              } into joinedPersonsSkills
              select joindPersonsSkills;

var result = persons.Where(x=>x.PerID==PerID).ToList();

我不确定这样做是否明智,我们以后再谈吧

您有两个表,
Persons
Skills
,具有一对多关系:每个
Persons
具有零个或多个
Skills
,每个
Skill
只属于一个
Person
,即
人员
,其主键值与
技能
外键在
PerId
中相同

要求:给我所有的人,每个人都有他们的技能

为此,您使用普通联接。结果可能是得到元组[Person 1,Skill 1],[Person 1,Skill 2],[Person 1,Skill 3]等等。Person 1的值会被一次又一次地复制

你想要的是拥有所有技能的人1,拥有所有技能的人2,拥有所有技能的人3等等。为此,你应该使用

现在,person 1只有一个对象,包含一个PerId、一个PerName和一个技能列表

结果将生成一个匿名对象。如果在这个过程之外需要这个对象,那么应该将结果放入一个真正的类对象中。简单地将线路更换为新的:

(person, skills) => new Person
{
    PerId = person.PerId,
    ...
});
注意:连接尚未执行,它仍然是IEnumerable。要执行查询并具体化对象,请使用foreach、ToList、FirstOrDefault等

// get Person 4 with all his Skills:
var requestedPerson = personsWithTheirSkills
    .Where(person => person.PerId == 4)
    .FirstOrDefault();
注意:可能没有人有PerId 4,即使有这样的人,他也可能没有任何技能

改进 数据库查询中较慢的部分之一是将所选数据从数据库管理系统传输到进程。因此,只选择实际计划使用的数据是明智的

在上面的示例中,我只使用了Person 4的数据,但所有Person的所有数据都已传输到您的流程中

显然,您有使用Dapper执行SQL查询的类。这些课程能让你学到人和技能

如果你必须定期询问<>代码>具有技能的人<代码>,请考虑创建一个函数来为你取回这个函数,让SQL和dpor执行<代码> GROMPION/<代码>。您可以命令您的简洁查询的程序员为此创建一个函数(或者自己创建)。可以找到一个示例,说明如何请求包含多个子项的项。我的印象是Dapper的新版本已经实现了此功能。

谢谢您的帮助

人员和技能是我理解解决方案的一个简单例子

我的问题是,我在200毫秒内列出了2000多个数据集。如果我加入sql计算(技能),查询大约需要14秒

如果我使用dapper将其加入到每个人的列表对象中,大约需要9秒。可能我使用的是1.50.2版,由于框架原因,无法更新到更新的版本

所以我决定将其与linq结合以提高性能,现在我测试它


感谢Harald Coppoolse的回答

不要加入。ORM的工作是从实体的关系中创建适当的SQL语句。我说实体而不是表是有原因的。ORM将表及其关系映射到对象,而不将表作为对象公开。如果它没有映射他们之间的关系,那就没有用了。在你的ORM中应该有一种机制,可以自动填充
PerSkills
,而不需要你加入它。你不需要做任何事情,只需要编写
myContext.Persons.Where(p=>someCondition.ToList()
,就可以同时获得人员和他们的技能。如果您不能做到这一点,那么上下文的配置就有问题。
(person, skills) => new Person
{
    PerId = person.PerId,
    ...
});
// get Person 4 with all his Skills:
var requestedPerson = personsWithTheirSkills
    .Where(person => person.PerId == 4)
    .FirstOrDefault();