Issue with IQueryable<object> and List<string> - c#

How to convert Object to List.
Can anybody tell me how to fix this issue.
This is the Error I am getting.

The problem is that your list is a List<string>, but your query returns a collection of baObject. You need to either use ToString() on this, or change your query to return a specific member.
The first option would look like:
descList.AddRange(query2.Select(ba => ba.ToString()).ToList());
The second (more likely option) could be as simple as:
descList.AddRange(query2.Select(ba => ba.Name).ToList());
(This is assuming baObject.Name is the property you want to list.)

Related

Remove single item from a list inside a dictionary

This feel really simple but I tried many scripts and nothing works.
I have an interface with Id field - named ITrust,
And I have a dictionary - Dictionary<string, Ilist<ITrust>>.
Now I'm trying to remove a single object from the list inside the dictionary but can't find the right script.
I tried some things like that:
dictionaryName[keyName].Remove(x => x.Id == Id);
But it raise an exception -
Cannot convert lambda expression to type ITrust because it is not a delegate type
Any one know the right script or maybe if there is a problem with might I try to do?
First off, that's a compilation error, not an exception. And second, stop using IList<> if you don't understand what it means.
If you use a normal List<>, you have a List.RemoveAll function that does exactly what you want.

Is there any way to make right to left value assigning in linq or in any other way

The title is pretty unclear. But I couldn't find the proper words. Generally Linq works in the below syntax
MyList.Where().Select(x => {MyFunction(x);})
It is good in ordinary conditions but in some situation like in my case. I am creating a tree structure using dictionary. In this if I want to add a set
Set.Foreach(x => {(MyDict[logEvent.level][logEvent.event][logEvent.subevent][logEvent.filePath]).Add(x);});
But it would be nice if I can do like below
(MyDict[logEvent.level][logEvent.event][logEvent.subevent][logEvent.filePath]).Add(MySet.Foreach(x => {return x;}));
Is there any way possible to dothis ?
You can do it, if object stored in Dict has AddRange method which accepts IEnumerable<T>. But you should ski[ ForEach and just pass MySet:
MyDict[logEvent.level][logEvent.event][logEvent.subevent][logEvent.filePath]).AddRange(MySet);

InvalidOperationException while sorting an ObservableCollection

In my program I have TreeView nodes that I need to be able to shift up and down, basically change the order. My TreeView is an ObservableCollection of a specific Data Model. Each node has a property called "Rank", this is the value that I would like to sort the collection by. With that being said I referred to this question. From that question I discovered this blog page. I am attempting the second method involving the sort function of a List.
This is the example that I am looking at:
List<Person> list = new List<Person>(people);
list.Sort();
Please note that the "Rank" value of each node is in working order and changing correctly. I just need to find a way to re-order the collection based off of that property and reflect it in the View.
My Problem: When trying to implement the above solution I get an InvalidOperationException. I feel like I do not understand how to tell the List to sort based off of rank.
What my code looks like:
List<TreeModel> sortedTree = new List<TreeModel>(TreeCollection);
sortedTree.Sort();
What am I missing here? How do I sort the collection based off of the rank property and reflect those changes in the view?
Thank you.
*I believe I may have posted about this before, so if for some reason this question is too similar my older one, I'll just delete the old one.
Sort throws InvalidOperationException its component type does not have a default comparison:
The default comparer Comparer.Default cannot find an implementation of the IComparable generic interface or the IComparable interface for type T.
You can however supply the comparison as the first parameter to Sort:
sortedTree.Sort((x, y) => x.Rank.CompareTo(y.Rank));
To pass the sorted items back to the original collection, you could either clear/repopulate CurrentCollection, or simply assign it a new instance (don't forget to RaisePropertyChanged if you do the latter):
CurrentCollection = new ObservableCollection<TreeModel>(sortedTree);
You need to pass property name on which you want to sort your list like this -
sortedTree = sortedTree.OrderBy(m => m.Rank).ToList();

DbSortClause expressions must have a type that is order comparable parameter Name :Key

I am using Linq to entity and have the following query
IQueryable<DomainModel.User> userResult =
userResult.OrderBy(u => u.UserClientRoles.OrderBy(r => r.Role.RoleName));
But I am getting this error
DbSortClause expressions must have a type that is order comparable
parameter Name :Key
and it returns an empty collection.
Any idea what's going on?
.OrderBy(), when working with databases, is supposed to take in a delegate that returns only a single property that represents a column in your database. I'm not sure what you're trying to do, but it looks like
u.UserClientRoles.OrderBy(r => r.Role.RoleName)
Will return an enumeration of values, which can't be ordered.
I had the same problem, I solved it using this:
your code:
IQueryable<DomainModel.User> userResult = userResult.OrderBy(u => u.UserClientRoles.OrderBy(r => r.Role.RoleName));
my code:
List<Membership> results = new List<Membership>();
results.AddRange(memberships.OrderBy(m => m.Roles));
memberships = results.AsQueryable();
coincidences:
*.OrderBy(m => m.Roles)
solution:
*.OrderBy(m => m.Roles.Select(r => r.RoleId).FirstOrDefault())
possible problem's reason:
Maybe, you did what I did, and cause that 1 user/member could have more than 1 role in the same membership. That made a conflict with/to OrderBy() because the application can just "order" a single element at the time, when she call the Role (which is an ICollection of elements) the instead receive more than 1 element with no kind of priority's levels (even when we could assume that the application will take the role's index as priority's base level, actually its don't).
solution's explaination:
When you add the *.Select(r => r.RoleId), you are specifying to the application which element will be used to OrderBy(). But, as you shall see when you maybe reached at this point, just by using the *.Select(r => r.RoleId) could be not enough, because the application is still receiving multiple results with the same priority's level. Adding *.Select(r => r.RoleId).FirstOrDefault() you are basically saying: "...I don't care how many results you received from that element, just the focus on the first result, or order them by its default..." (default normally means EMPTY or NULL).
additional information:
I used non-official's simple concepts/meanings to explain a complex solution with simple words, which means that you could maybe have problems to find similar posts in the web by using the words/concepts used in this "answer". Otherwise, the code itself works and you shouldn't not have any problem by applying it and/or modifying it by yourself. GOOD LUCK!!! (^_^)
In my case, I was accidentally trying to order by an object instead of ordering by one of it's properties.
You should you use
var query = from Foo in Bar
orderby Foo.PropertyName
select Foo;
Instead of
var query = from Foo in Bar
orderby Foo
select Foo;
Note: you will get the same behaviour event if there is an override on Foo's ToString() method.

LINQ filter by type on list from dictionary value

Think this is a very basic question, but it's my first LINQ query and I'm completely stuck:
I have a dictionary with string key and list value (see definition below) and want to pull out elements of a list of a particular type having selected the list by the dictionary key.
IDictionary<string, IList<MyBaseType>> dataItemMap;
Where MySubType extends MyBaseType.
My dodgy query is:
string identCode = "foo";
IEnumerable<MySubType> query =
from entry in dataItemMap
where entry.Key == identCode
select entry.Value.OfType<MySubType>();
And the error message (from LinqPad):
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<MySubType>>'
to 'System.Collections.Generic.IEnumerable<MySubType>'.
An explicit conversion exists (are you missing a cast?)
The problem is clearly in the entry.Value.OfType<> but how can I specify the lists elements? I'm looking for something like entry.Value.Items.OfType<> ?
thanks.
I think you want something like this:
IEnumberable<MySubType> query = dataItemMap[identCode].OfType<MySubType>();
This will get the list with the given key, and then filter it to return only MySubType elements.
EDIT: I've been focusing on why the existing solution didn't work (and the general problem of "I've got a list of values for each element, and I want to flatten it") rather than taking a step back. As Andy's answer shows, you should almost certainly use the fact that it's a dictionary - turning it from an O(n) operation to O(1) :)
Two caveats:
Your current code will always perform an ordinal, culture-insensitive comparison with identCode and the dictionary keys; using the dictionary lookup will use whatever comparer it was constructed with.
Your current code will return an empty sequence if identCode isn't found in the dictionary; the dictionary indexer will throw an exception. You can use TryGetValue if you want to avoid that.
Note that if you know that all the elements in the last you're picking are actually of the right type, it would probably be better to use Cast than OfType:
var query = dataItemMap[identCode].Cast<MySubType>();
I generally prefer Cast to OfType when both would work, as it means that if my assumptions about the data in the sequence prove incorrect, I find out about it with an exception rather than silently missing data.
Note that Cast will also return null elements, whereas OfType won't.
No, the problem isn't in using OfType<> - it's that you've ended up with a sequence of sequences, but you're trying to assign that to a single sequence.
Either change the return type, or use another from clause to flatten the results:
IEnumerable<MySubType> query = from entry in dataItemMap
where entry.Key == identCode
from value in entry.Value.OfType<MySubType>()
select value;
I'd be tempted to use the extension methods directly:
var query = dataItemMap.Where(e => e.Key == identCode)
.SelectMany(e => e.Value.OfType<MySubType>());

Categories

Resources