0

I want to compare two list with objects of two different classes. These are the classes:

namespace AngularWebApplication.Models
{
    public class AggregationLevelConfigurationPresentation
    {
        public byte AggregationLevelConfigurationId { get; set; }
        public int ProductionOrderId { get; set; }
        public string Name { get; set; }
        [ ... ]
    }
}

public class AggregationLevelConfiguration : IEquatable<AggregationLevelConfiguration>
{
    public byte AggregationLevelConfigurationId { get; set; }
    public int ProductionOrderId { get; set; }
    public string Name { get; set; }
    [ ... ]
}

I want to get the elements in presentations list that are not in currentLevels:

List presentations; List currentLevels;

List<Models.AggregationLevelConfigurationPresentation> newLevels =
    presentations
        .Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId })
        .Except(currentLevels.Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId }))
        .ToList();

But I get the following error when I do the Except:

Error   CS0029  Cannot implicitly convert type 
'System.Collections.Generic.List<<anonymous type: byte AggregationLevelConfigurationId, int ProductionOrderId>>' to 
'System.Collections.Generic.List<AngularWebApplication.Models.AggregationLevelConfigurationPresentation>'

I think the problem is in the new { l.AggregationLevelConfigurationId, l.ProductionOrderId } but I don't know how to do the Except with list of objects from different classes.

I need the objects in presentations list that they aren't in currentLevels using AggregationLevelConfigurationId and ProductionOrderId as primary key.

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • 2
    Could try and rephrase the title? I couldn't make sense of it until reading the question. – Fildor Nov 13 '17 at 08:58
  • You are selecting anonymus types, so why you expect that `ToList` creates a `List`? – Tim Schmelter Nov 13 '17 at 08:58
  • @TimSchmelter I expect to have a `List`. – VansFannel Nov 13 '17 at 09:00
  • @Fildor I have changed but I'm not very good in English, so I don't know if the title is correct or not now. – VansFannel Nov 13 '17 at 09:01
  • I need the objects in `presentations` list that they aren't in `currentLevels` using `AggregationLevelConfigurationId` and `ProductionOrderId` as primary key. I think you don't have understood the question. – VansFannel Nov 13 '17 at 09:15
  • Please, reopen it. This is not a duplicate question. Every time I like less stackoverflow. It is getting harder and harder to ask something without someone's hand leaving a negative vote because the SO rules are not followed to the letter. Think that not everyone is native English and can not express what they think correctly. You can ask if something is not understood. – VansFannel Nov 13 '17 at 09:17
  • I've reopened that question because it is indeed not duplicate of questions provided as duplicates. – Evk Nov 13 '17 at 09:18
  • 1
    I'd suggest to not use `Except` in this case. Instead, you can do something like `presentations.Where(p => !currentLevels.Any(l => p.AggregationLevelConfigurationId == l.AggregationLevelConfigurationId))` – Evk Nov 13 '17 at 09:20
  • @Evk Thanks. I think so about `Any`. It seems to be a better option. – VansFannel Nov 13 '17 at 09:20
  • _"It is getting harder and harder to ask something without someone's hand leaving a negative vote because the SO rules are not followed to the letter"_ - no, you are nearing **a thousand (!) questions** and you still don't get that you need to show your research. This has absolutely nothing to do with how fluent you are in English. You required an edit to your question, which in turn required an edit to the correct answer to your initial question, because you were unable to properly describe your problem to begin with. So once again, read [ask], create a [mcve] and show what you've tried. – CodeCaster Nov 13 '17 at 10:54
  • @Evk the initial question was a compiler error, which _was_ answered by the duplicates I found. The OP then edited the question because they needed different criteria for how the data was built up, which is a different question altogether. So, OP, if we'd follow the letter of the law on Stack Overflow which you complain about, we were to revert those edits to your question and the answer, and re-close as a duplicate, because the initial question was answered. – CodeCaster Nov 13 '17 at 10:57
  • 1
    @CodeCaster, in all editions question has "I want to get the elements in presentations list that are not in currentLevels". Compiler error is just by-product of OPs attempt to do this. – Evk Nov 13 '17 at 11:16
  • @CodeCaster I think is clear that I need a `List` when the code above the compiler error has that assignment. I don't think I need to explain the code but there were a lot of negative votes and duplicate votes, so I decided to explain it adding the bold paragraph. This is why I said that. – VansFannel Nov 13 '17 at 11:21
  • @Evk there were a compiler error and a logic error in the question. We ask one question per question. I voted to close as duplicate of the compiler error. The OP should've figured out that one before asking about the logic error. Perhaps try reading a couple of their earlier chameleon questions. – CodeCaster Nov 13 '17 at 11:23
  • People that have voted this question as duplicate is because they haven't read or understood the question. It is clear that what I need: **I want to get the elements in presentations list that are not in currentLevels:** And it is clear that if I assign an anonymous type to a list of something I will get a compiler error. The compiler error is the result of I have tried, not the question. I haven't been looking for two answers. I haven't asked about the compiler error. Please, read the question and if you don't understand the question ask me before start casting down votes or duplicate votes. – VansFannel Nov 13 '17 at 12:25
  • So you don't want the compiler error fixed? You'll accept a non-compiling answer? When asking for help with a logic problem, you need to make sure that the code compiles, so the reader can focus on all that matters: fixing your logic. Of which in itself duplicates exist, so again: **show your research and make sure your question focuses on one problem**. You should know that after having asked almost 1000 questions. If you'd spent even the tinyest amount of time to fix the compiler error before posting, we wouldn't have had this discussion and I wouldn't have dupe-voted, not for those Q's. – CodeCaster Nov 13 '17 at 12:30
  • @CodeCaster: **I want to get the elements in presentations list that are not in currentLevels**. This was the question. – VansFannel Nov 13 '17 at 12:34
  • You did, and you then proceeded to show some code that, at a glance, seemed to do exactly what you want, **followed by a compiler error**. Tim's initial answer did exactly what was explained in the duplicates. Can you take a step back and look at that verison of your question, and honestly tell that you would expect any reader to just ignore that compiler error and focus on fixing the logic problem in your code? You did not explain what that code did or didn't do. You posted a **compiler error**. Which was fixed by the duplicates I found. After which you could have continued with your work. – CodeCaster Nov 13 '17 at 12:38
  • Anyway if your question is not about the compiler error but indeed about the logic part, see [Filtering a list using except on multiple properties](https://stackoverflow.com/questions/28766052/), [How to use linq `Except` with multiple properties with different class?](https://stackoverflow.com/questions/28782437/), [LINQ: Use .Except() on collections of different types by making them convertible/comparable?](https://stackoverflow.com/questions/9998549/), [List.except on custom class](https://stackoverflow.com/questions/17782733/), and so on. Search before asking. – CodeCaster Nov 13 '17 at 12:48

2 Answers2

4

Your Execept-query selects anonymous types, so ToList doesn't create a List<AggregationLevelConfigurationPresentation>. You have to create instances of this class:

List<AggregationLevelConfigurationPresentation> newLevels = presentations
        .Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId })
        .Except(currentLevels.Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId }))
        .Select(x => new AggregationLevelConfigurationPresentation 
        { 
            AggregationLevelConfigurationId = x.AggregationLevelConfigurationId,  
            ProductionOrderId = x.ProductionOrderId
         })
        .ToList();

I need the objects in presentations list that they aren't in currentLevels using AggregationLevelConfigurationId and ProductionOrderId as primary key.

Then you could use Join:

var except = presentations
        .Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId })
        .Except(currentLevels.Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId }));

var newLevels = from x in except
                join p in presentations 
                on x equals new { p.AggregationLevelConfigurationId, p.ProductionOrderId }
                select p;
List<AggregationLevelConfigurationPresentation> newLevelList = newLevels.ToList();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I doubt OP wants this. He wants items from original `presentations` list, not new items (which are even with only 2 properties filled). – Evk Nov 13 '17 at 09:08
  • But this returns a list of objects with only a value in `AggregationLevelConfigurationId` and `ProductionOrderId` and I need the objects in `presentations` list that they aren't in `currentLevels` using `AggregationLevelConfigurationId` and `ProductionOrderId` as primary key. – VansFannel Nov 13 '17 at 09:14
0

Following Evk comment, this is how I have solved this problem:

List<Models.AggregationLevelConfigurationPresentation> newLevels =
     presentations.Where(p => !currentLevels.Any(l => p.AggregationLevelConfigurationId == l.AggregationLevelConfigurationId && p.ProductionOrderId == l.ProductionOrderId));
VansFannel
  • 45,055
  • 107
  • 359
  • 626