Linq检查集合中的相等值,并将值赋给其他集合

时间:2015-09-02 16:16:47

标签: c# linq

我有一个名为Message and History的模型。历史有另一个模型,即List

消息模型具有以下属性,

MessageId,Title,Content,FileID,FileName 

历史模型

Title,Content,List<File> 

文件模型: ----这是历史模型中的列表

FileId,FileName

MessageModel数据如下, MessageId标题内容FileId FileName 101

MessageId  Title    Content   Fileid FileName  
100      1st title  1st content 1    User.pdf  
100      1st title  1st content 2    Log.txt  
100      1st title  1st content 3    manual.doc  
101      2nd title  2nd content 4    dummy.txt   
102      3rd title  3rd content Null     Null  
103      4th title  4th content Null     Null  

场景:单个messageid可以有多个fileid,filename或没有fileid,filename。

我想将消息标题的不同值,内容分配给历史模型标题和内容以及Fileid,FileName分配给文件模型列表

我的历史记录模型应具有以下值,

Title     Content       Fileid  FileName
1st title   1st content    1     User.pdf
                            2    Log.txt
                            3    manual.doc
2nd title   2nd content    4     dummy.txt
3rd title   3rd content   Null   Null
4th title   4th content   Null   Null

Messageid在这里是独一无二的。 我学会了在linq中编写简单的查询。对于上述情况,任何人都可以建议如何做。

2 个答案:

答案 0 :(得分:1)

您可以使用GroupBy

假设messages是一个IEnumerable,以下内容应该是您所追求的:

var history = messages.GroupBy(m => new { m.Title, m.Content }, (group, data) => new HistoryModel()
{
    Title = group.Title,
    Content = group.Content,
    Files = data.Select(k => new File() 
                                { 
                                    FileId = k.Fileid, 
                                    FileName = k.FileName
                                }
                        ).ToList(),
});

这基本上是指按照TitleContent属性对邮件进行分组。对于每个组,lambda被称为传递group,这是一个匿名类型,包含组的详细信息(即标题和内容)和dataIEnumerable<MessageModel>包含每个MessageModel 1}}在组中。由此我们可以构建HistoryModel

的列表

OPs问题后编辑

以上内容只能在history中为您提供4个元素。我用来测试它的完整列表是:

class MessageModel
{
    public string MessageId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public string Fileid { get; set; }
    public string FileName { get; set; }

    public MessageModel(string m, string t, string c, string f, string f2)
    {
        MessageId = m;
        Title = t;
        Content = c;
        Fileid = f;
        FileName = f2;
    }
}

class HistoryModel
{
    public string Title { get; set; }
    public string Content { get; set; }
    public List<File> Files { get; set; }
}

class File
{
    public string FileId { get; set; }
    public string FileName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<MessageModel> messages = new List<MessageModel>();
        messages.Add(new MessageModel("100", "1st title", "1st content", "1", "User.pdf"));
        messages.Add(new MessageModel("100", "1st title", "1st content", "2", "Log.txt"));
        messages.Add(new MessageModel("100", "1st title", "1st content", "3", "manual.doc"));
        messages.Add(new MessageModel("101", "2nd title", "2nd content", "4", "dummy.txt"));
        messages.Add(new MessageModel("102", "3rd title", "3rd content", null, null));
        messages.Add(new MessageModel("103", "4th title", "4th content", null, null));

        var history = messages.GroupBy(m => new { m.Title, m.Content }, (group, data) => new HistoryModel()
        {
            Title = group.Title,
            Content = group.Content,
            Files = data.Select(k => new File()
            {
                FileId = k.Fileid,
                FileName = k.FileName
            }).ToList(),
        });

        foreach (var h in history)
        {
            Console.WriteLine(h.Title + " " + h.Content);

            foreach (var file in h.Files)
            {
                Console.WriteLine("\t" + file.FileId + " " + file.FileName);
            }
        }

        Console.ReadLine();
    }

}

以上产生输出:

  

第1名第1内容
  1 User.pdf
  2 Log.txt
  3 manual.doc
  第二名第二内容
  4 dummy.txt
  第3名第3名内容

第4名第4内容

答案 1 :(得分:1)

您可以使用Group by子句对公共属性(MessageId,Title和Content)进行分组。然后使用它作为ke,然后可以使用Select子句来构建HistoryModel。

下面的完整示例(注意.Dump()来自LinqPad)

void Main()
{
    var messages = new List<MessageModel>
    {
        new MessageModel(100,"1st title","1st content", 1,"User.pdf"),
        new MessageModel(100,"1st title","1st content",  2,"Log.txt"),
        new MessageModel(100,"1st title","1st content", 3,"manual.doc"),
        new MessageModel(101,"2nd title","2nd content", 4,"dummy.txt"),   
        new MessageModel(102,"3rd title","3rd content" ),
        new MessageModel(103,"3rd title","3rd content")
    };

    var groupedMessages = 
    messages.GroupBy(x=> new {x.MessageId, x.Title, x.Content})
            .Select(x=> new HistoryModel
                          {
                            MessageId =  x.Key.MessageId,
                            Title = x.Key.Title,
                            Content = x.Key.Content,
                            Files = new List<FileModel>(x.Where( f=>  f.FileId != null)
                                                         .Select( g => new FileModel(g.FileId,  g.FileName)))
                          });

    groupedMessages.Dump();
}

// Define other methods and classes here
public class MessageModel
{
    public int MessageId {get; set;}

    public string Title {get; set;}

    public string Content {get; set;}

    public int? FileId {get; set;}

    public string FileName {get; set;}

    public MessageModel(int id, string title, string content, int? fileId = null, string fileName= null)
    {
        MessageId = id;
        Title =  title;
        Content = content;
        FileId = fileId;
        FileName = fileName;
    }
}

public class HistoryModel
{
    public int MessageId {get; set;}

    public string Title {get; set;}

    public string Content {get; set;}

    public List<FileModel> Files{get; set;} = new List<FileModel>();

}

public class FileModel
{
    public int? FileId {get; set;}

    public string FileName {get; set;}

    public FileModel(int? id, string name)
    {
        FileId = id;
        FileName = name;
    }
}