Compare 2 generic lists and return missing values from list b - linq

I have 2 generic lists.
List 1 is populated with products from a database and List 2 is populated with products from a webservice.
I am wanting to compare lists and any values that are not in List 2 add them to List 3.
I have tried
List<ProductModel> productsToAdd = productsInDatabase.Except(productsFromService).ToList();
However all results are displayed even tho product already is in the database.
What am I doing wrong? do I need to somehow use Except but use an Id field?

Use overloaded version of Except method and pass equality comparer: MSDN

Related

laravel lists is giving wrong ids for the column values

I am fetching a list of rosters
$rostersList = Roster::where('school_id', $this->schoolId)->get()->lists('id', 'name');
$rostersList->prepend('Select Roster');
but the ids always start from 0,1,2 why is that? However according to the where condition the returned list should not be starting from 0 or 1 but from 4. What can be the possible issue here?
When you prepend a single value without assigning a key with it, the collection gets re-keyed.
Laravel prepend lets you pass a second parameter to use as the key.
So you would want something like:
$rostersList->prepend('Select Roster', '');

Concatenating a LINQ query and LINQ sort statement

I'm having a problem joining two LINQ queries.
Currently, my (original) code looks like this
s.AnimalTypes.Sort((x, y) => string.Compare(x.Type, y.Type));
What I'm needing to do is change this based on a date, then select all data past that date, so I have
s.AnimalTypes.Select(t=>t.DateChanged > dateIn).ToList()
s.AnimalTypes.Sort((…
This doesn't look right as it's not sorting the data selected, rather sorting everything in s.AnimalTypes.
Is there a way to concatenate the two LINQ lines? I've tried
s.AnimalTypes.Select(t=>t.DateChanged > dateIn).ToList().Sort((…
but this gives me an error on the Sort section.
Is there a simple way to do this? I've looked around and Grouo and OrderBy keep cropping up, but I'm not sure these are what I need here.
Thanks
From your description, I believe you want something like:
var results = s.AnimalTypes.Where(t => t.DateChanged > dateIn).OrderBy(t => t.Type);
You can call ToList() to convert to a List<T> at the end if required.
There are a couple of fundamental concepts I believe you are missing here -
First, unlike List<T>.Sort, the LINQ extension methods don't change the original collections, but rather return a new IEnumerable<T> with the filtered or sorted results. This means you always need to assign something to the return value (hence my var results = above).
Second, Select performs a mapping operation - transforming the data from one form to another. For example, you could use it to extract out the DateChanged (Select(t => t.DateChanged)), but this would give you an enumeration of dates, not the original animal types. In order to filter or restrict the list with a predicate (criteria), you'd use Where instead.
Finally, you can use OrderBy to reorder the resulting enumerable.
You are using Select when you actually want to use Where.
Select is a projection from one a collection of one type into another type - you won't increase or reduce the number of items in a collection using Select, but you can instead select each object's name or some other property.
Where is what you would use to filter a collection based on a boolean predicate.

Trying to execute a WHERE IN: Invalid 'where' condition. An entity member is invoking an invalid property or method

I'm trying to get a list of cases whose AccountID is found in a previous list.
The error occurs on the last line of the following:
// Gets the list of permissions for the current contact
var perms = ServiceContext.GetCaseAccessByContact(Contact).Cast<Adx_caseaccess>();
// Get the list of account IDs from the permissions list
var customerIDs = perms.Select(p => p.adx_accountid).Distinct();
// Get the list of cases that belong to any account whose ID is in the `customerID` list
var openCases = (from c in ServiceContext.IncidentSet where customerIDs.Contains(c.AccountId) select c).ToList();
I'm not sure what the "invalid property" is the error is talking about. The code compiles, I just get the error at runtime.
The problem is the CRM Linq Provider. It doesn't support all of the available options that the Linq-to-objects provider offers. In this case, the CRM does not support the Enumerable.Contains() method.
where:
The left side of the clause must be an attribute name and the
right side of the clause must be a value. You cannot set the left side
to a constant. Both the sides of the clause cannot be constants.
Supports the String functions Contains, StartsWith, EndsWith, and
Equals.
You can work around this in one of two ways:
Rework your query to use a more natural join.
If a join is not possible, you can use Dynamic Linq to generate a list of OR clauses on each item in customerIDs. This would function similarly to Enumerable.Contains.
See my answer or the accepted answer to the question "How to get all the birthdays of today?" for two separate ways to accomplish this.

Linq match item in lookup column with multiple entries

I have list A that has a lookup to list B that allows multiple entries. One A to multiple related Bs - standard practice. I want to find A where B contains a reference to a particular instance of 'b'.
I've tried:
var As = from a in ARecs where a.Bs.Contains(b) select a;
But I get the usual 'multiple tables involved' error. How do I go about this please?
thanks in advance
the error I'm getting is "The query uses unsupported elements, such as references to more than one list, or the projection of a complete entity by using EntityRef/EntitySet."
The A and B list code is generated by SPMetal if that makes any difference
Some LINQ cannot be turned into CAML (did I forget to mention this was on SPMetal generated LINQ to Sharepoint - doh!) and needs to be performed as 2 queries - the first ToList then the 2nd on that list. This worked for me.
Var Bs = A.ToList().Where(record => record.Bs.Contains(b))

Combining Variable Numbers of Lists w/ LINQ

I have a list (List) of objects.
Each of those objects contains a list (List) of strings describing them.
I'm needing to create a dropdown containing all of the distinct strings used to describe the objects (Cards). To do this, I need a list of distinct strings used.
Any idea how/if this can be done with LINQ?
You can use the SelectMany extension method/operator to flatten a collection into the individual elements.
listOfObjects.SelectMany(x => x.DescriptionStrings).Distinct()
This will select all the strings out of the collection of description strings for each object in your list of objects.
LINQ has a Distinct function.
Assuming "_cards" exists as instance variable of List and Card.Descriptions returns the descriptions and "cardsComboBox" (in WinForms):
cardsComboBox.AutoCompleteSource = _cards.SelectMany(c => c.Descriptions).Distinct();
A reminder that that will be the list of card descriptions at the time of binding however. If you want to keep it synchronised when _cards get updated then you'll have to do some more fancy footwork or look at a reactive binding source. (We use Bindable.Linq)

Resources