Linq join返回重复的结果

时间:2017-07-24 03:38:33

标签: c# linq join duplicates

我正在使用LINQ试图获得我角色的所有衣服。

我的查询如下:

var characterList = from characters in ContextFactory.Instance.Characters
                    where characters.UserId == user.Id

                    join traits in ContextFactory.Instance.CharacterTraits
                    on characters.Id equals traits.CharacterId
                    join clothes in ContextFactory.Instance.CharacterClothes
                    on characters.Id equals clothes.CharacterId
                    select new { 
                        characters.Id, 
                        characters.Name, 
                        characters.Gender, 
                        characters.Level, 
                        characters.Money, 
                        characters.Bank, 
                        characters.LastLogin, 
                        characters.PlayedTime, 
                        traits, 
                        clothes };

然后我将它序列化为在javascript中用作JSON。

此代码为每个衣服返回一个用户,我希望它将所有衣服分组在一个数组中。我怎么能这样做?

目前的结果:

Image

谢谢

2 个答案:

答案 0 :(得分:3)

为此,您需要使用GroupJoin注意在加入结束时添加into

var characterList = from characters in ContextFactory.Instance.Characters
                    where characters.UserId == user.Id
                    join t in ContextFactory.Instance.CharacterTraits
                    on characters.Id equals t.CharacterId into traits 
                    join c in ContextFactory.Instance.CharacterClothes into clothes
                    on characters.Id equals c.CharacterId
                    select new { /* As before */ }

在MSDN上阅读更多内容:Perform Grouped Joins

请注意,如果您使用的是EF,则无需编写连接。正确定义导航属性并使用Include将以更少的工作量为您提供所需的内容。

最后,请注意即使有Where条件,这也会返回IEnumerable<>个结果。如果您只想要一条包含所有这些信息的记录,那么最后添加,包装全部,FirstOrDefault或更好仍然删除查询中的where子句并执行:

var character = (from characters in ContextFactory.Instance.Characters
                 join t in ContextFactory.Instance.CharacterTraits
                 on characters.Id equals t.CharacterId into traits 
                 join c in ContextFactory.Instance.CharacterClothes into clothes
                 on characters.Id equals c.CharacterId
                 select new { /* As before */ }).FirstOrDefault( x=> x.id = user.Id);

答案 1 :(得分:0)

见下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();

            var characterList = (from characters in ContextFactory.Instance.Characters
            where characters.UserId == user.Id
            join traits in ContextFactory.Instance.CharacterTraits
            on characters.Id equals traits.CharacterId
            join clothes in ContextFactory.Instance.CharacterClothes
            on characters.Id equals clothes.CharacterId
            select new { characters = characters, traits = traits, clothes = clothes })
            .GroupBy(x => x.characters.Id)
            .Select(x => new { 
                id = x.FirstOrDefault().characters.Id, 
                name = x.FirstOrDefault().characters.Name, 
                gender = x.FirstOrDefault().characters.Gender, 
                level = x.FirstOrDefault().characters.Level, 
                money = x.FirstOrDefault().characters.Money, 
                bank = x.FirstOrDefault().characters.Bank, 
                lastLogin = x.FirstOrDefault().characters.LastLogin, 
                playedTime = x.FirstOrDefault().characters.PlayedTime, 
                traits = x.FirstOrDefault().traits, 
                clothes = x.Select(y => y.clothes.clothes).ToArray()
            }).FirstOrDefault();

        }
    }

    public class ContextFactory
    {
        public static Instance Instance = null;
    }
    public class Instance
    {
        public List<Characters> Characters;
        public List<CharactersTraits> CharacterTraits;
        public List<CharactersClothes> CharacterClothes;
    }
    public class Characters
    {
        public int Id;
        public int UserId;
        public string Name;
        public string Gender;
        public string Level;
        public string Money;
        public string Bank;
        public string LastLogin;
        public string PlayedTime;
    }
    public class CharactersTraits
    {
        public int CharacterId;
    }
    public class CharactersClothes
    {
        public int CharacterId;
        public string clothes;
    }
    public class User
    {
        public int Id;
    }
}