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()
};