I have this entities:
public class Parent: AllDependant
{
/*Properties goes here*/
}
public class Children: AllDependant
{
/*Properties goes here*/
}
Then I have allDependants variable with typeof List<AllDependant> which will keep some of parents and childrens entitiy in mix.
Later on, I want to select from them and do something like this:
var selectedDependantInfos = allDependants
.Select(dependant =>
{
if (dependant is Parent)
{
var parent = dependant as Parent;
return new { Name = parent.Name, SomeSpecialInfo = parent.ParentInfo };
}
else
{
var child = dependant as Children;
return new { Name = child.Name, SomeSpecialInfo = child.ChildInfo }
}
});
Note the specific property for child and parent require me to cast and get the property to a new model for UI display which is not entity concern. I cannot put the special property in AllDependant base class because I need to refactor the property name on so many files including *.ascx which is troublesome. However it done by using the Linq Select extension method above but I just thinking of this:
Question: How can I do the same in Linq Query?
This will give error on the select keyword and the curly braces:
var selectedDependantInfos = from dependant in allDependants
select
{
/* the same if statement goes here */
}
You would use the conditional operator and get something like
from dependant in allDependants
select dependant is Parent
? new { Name = (dependant as Parent).Name, /* Parent fields */ }
: new { Name = (dependant as Children).Name, /* Child fields */ }
But as you see that is not a great improvement. There's no convenient place to do the type-cast.
The better option would seem to move the Name and SpecialInfo properties to a base class (AllDependant or a special intermediate class).
Sibling class in allDependants will result in NullReferenceException here - InvalidCastException is always more informative, so I'd use a cast - Jacek Gorgoń 2012-04-04 07:12
An alternative would be:
var parents = allDependants.OfType<Parent>.Select(p => new { Name = p.Name, .... };
var children = allDependants.OfType<Children>.Select(c => new { Name = c.Name, .... };
var combined = parents.Concat(children);
The disadvantage of this approach would be that addDependants would be iterated over twice.
allDependants twice and perform the type check twice but on the other hand is safe if allDependants will contain an AllDependant not being Parent or Child (as opposed to OP solution) - Jacek Gorgoń 2012-04-04 07:09
from e in entities select e.column syntax - CallMeLaNN 2012-04-04 13:15
Another way of using Reflection
var selectedDependantInfos = from p in allDependants
let key = p is Parent ? "ParentInfo" : "ChildInfo"
select new {
Name = p.GetType().GetProperty("Name").GetValue(p, null).ToString(),
SomeSpecialInfo = p.GetType().GetProperty(key).GetValue(p, null).ToString()
};