简体   繁体   English

使用LINQ与Select和Distinct方法

[英]Using LINQ with Select and Distinct Methods

If I use the following code in LINQPad to query my database I get the desired results: 如果我在LINQPad中使用以下代码来查询我的数据库,我会得到所需的结果:

LoadTables.Where(o=> o.Approver== "Name Name" ||o.Approver== "Name.Name").Select(o=>o.SubmittedBy).ToList().Distinct()

However, if I amend this and put it into my code, I get an error: 但是,如果我修改它并将其放入我的代码中,我会收到一个错误:

public IEnumerable<LoadTable> TableList;
TableList = _context.LoadTable.Where(o => o.Approver == GetADDetails.displayName || o.Approver == GetADDetails.userName).Select(o => o.SubmittedBy).ToList().Distinct();

The error returned is: 返回的错误是:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'System.Collections.Generic.IEnumerable<App.Models.LoadTable>' An explicit conversion exists. 无法将类型'System.Collections.Generic.IEnumerable<string>' to 'System.Collections.Generic.IEnumerable<App.Models.LoadTable>' An explicit conversion exists.隐式转换'System.Collections.Generic.IEnumerable<string>' to 'System.Collections.Generic.IEnumerable<App.Models.LoadTable>' An explicit conversion exists.

Where am I going wrong? 我哪里错了?

For context, see previous quested here: 有关上下文,请参阅此前的问题:

Using LINQ to loop through data and display in a table 使用LINQ循环数据并在表格中显示

Currently it's returing a new table for every match, I'm trying to get it to return a table per user. 目前它正在为每场比赛重新推出一张新桌子,我试图让它为每个用户返回一张桌子。

Remove from the Linq expresion Select(o => o.SubmittedBy) and put Distinct() before of ToList() : 从Linq expresion中删除Select(o => o.SubmittedBy)并在ToList()之前放置Distinct() ToList()

public IEnumerable<LoadTable> TableList;
TableList = _context.LoadTable.Where(o => o.Approver == GetADDetails.displayName || 
  o.Approver == GetADDetails.userName).Distinct().ToList();

You are selecting a string property 您正在选择字符串属性

**.Select(o => o.SubmittedBy)**

this return IEnumerable<string> 这返回IEnumerable<string>

you need something like below 你需要像下面这样的东西

_context.LoadTable.Where(o => o.Approver == GetADDetails.displayName || o.Approver == GetADDetails.userName).Distinct().GroupBy(p => p.SubmittedBy).Select(grp => grp.FirstOrDefault());

Alas you forgot to tell us what kind of objects are in the sequence that is returned by _context.LoadTable . 唉,你忘了告诉我们_context.LoadTable返回的序列中有哪些对象。 Looking at your code, it seems that it returns an enumerable sequence of objects, where every object has at least a property SubmittedBy . 看看你的代码,似乎它返回一个可枚举的对象序列,其中每个对象至少有一个属性SubmittedBy

Looking at your error, it seems that SubmittedBy is a string property. 看看你的错误,似乎SubmittedBy是一个字符串属性。

If you had split your code into smaller pieces and used proper identifiers, you would soon have seen your problem. 如果您将代码拆分成较小的部分并使用了正确的标识符,那么很快就会看到您的问题。

Let's examine your code: 我们来检查你的代码:

IEnumerable<LoadTable> TableList = _context.LoadTable
    .Where(o => o.Approver == GetADDetails.displayName || o.Approver == GetADDetails.userName)
    .Select(o => o.SubmittedBy)
    .ToList()
    .Distinct();

_context.LoadTable returns an IEnumerable sequence of items unknown by me, so let's assume it is a sequence of Notes : _context.LoadTable返回我不知道的IEnumerable项目序列,所以我们假设它是一系列Notes

IEnumerable<Note> notes = _context.LoadTable;

It could be that LoadTable returns an IEnumerable instead of IEnumerabl<Note> , in that case you should cast the loaded table. 可能是LoadTable返回IEnumerable而不是IEnumerabl<Note> ,在这种情况下你应该转换加载的表。

The next statements: 接下来的陈述:

IEnumerableM<Note> notesApprovedByUser = notes
    .Where(note => note.Approver == GetADDetails.displayName 
                || note.Approver == GetADDetails.userName);
IEnumerable<string> submitters = notesApprovedByUser
    .Select(note => note.SubmittedBy);
List<string> submitterList = submitters.ToList();
IEnumerable<string> distinctSubmitters = submitterList.Distinct();

It is easy to see that a sequence of strings can't easily be converted to a sequence of LoadTables . 很容易看出,一串字符串不能轻易转换为LoadTables序列。

The question is: do you want unique LoadTables , or do you want for every submitter all hist submitted notes? 问题是:你想要独特的LoadTables ,还是你想要每个提交者所有的hist提交的笔记? In that case you'll have to Groupby instead of Select : 在这种情况下,您将不得不使用Groupby而不是Select

.Where(note => ...)
.GroupBy(note => note.SubmittedBy,  // make groups of Notes submitted by the same submitter
   // parameter resultSelector: take every submitter and all notes that
   // were submitted by this submitter to make a new object
   (submittedBy, notesSubmittedByThisSubmitter) => new
   {
       // select the properties you plan to use
       Submitter = submittedBy
       LoadTables = notesSubmittedByThisSubmitter.Select(note => new LoadTable
       {
           ... again: select the properties you need
       })
       .ToList(),
   });

Remember: keep an IEnumerable<...> an IEnumerable<...> as long as possible. If not necessary, don't do a 记住: IEnumerable<...> as long as possible. If not necessary, don't do a保持IEnumerable<...> IEnumerable<...> as long as possible. If not necessary, don't do a IEnumerable<...> as long as possible. If not necessary, don't do a ToList() before you return. If your query returns 1000 items, and your caller will only do IEnumerable<...> as long as possible. If not necessary, don't do a before you return. If your query returns 1000 items, and your caller will only do IEnumerable<...> as long as possible. If not necessary, don't do a ToList() before you return. If your query returns 1000 items, and your caller will only do before you return. If your query returns 1000 items, and your caller will only do FirstOrDefault , or Take(3).ToList()`, it would be a waste of processing power to create your complete list before you return. If your query returns 1000 items, and your caller will only do FirstOrDefault , or Take(3).ToList()`,那么创建完整列表将浪费处理能力

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM