Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Full object projection with additional values in LINQ

Is it possible to project every property of an object and add more, without specifically listing them all. For instance, instead of doing this:

   var projection = from e in context.entities
                    select new QuestionnaireVersionExtended
                    {
                        Id = e.Id,
                        Version = e.Version,
                        CreationDate = e.CreationDate,
                         ... 
                         many more properties
                         ...
                        NumberOfItems = (e.Children.Count())
                    };

Can we do something like this:

   var projection = from e in context.entities
                    select new QuestionnaireVersionExtended
                    {
                        e,
                        NumberOfItems = (e.Children.Count())
                    };

Where it will take every property from e with the same name, and add the "NumberOfItems" property onto that?

like image 839
CodeGrue Avatar asked Jun 24 '10 19:06

CodeGrue


3 Answers

No this is not possible. The select clause of a LINQ expression allows for normal C# expressions which produce a value. There is no C# construct which will create an object via an object initializer in a template style manner like this. You'll need to either list the properties or use an explicit constructor.

like image 97
JaredPar Avatar answered Nov 12 '22 21:11

JaredPar


If you add a constructor to QuestionnaireVersionExtended that takes your entity plus NumberOfItems, you can use the constructor directly:

var projection = from e in context.entities
     select new QuestionnaireVersionExtended(e, NumberOfItems = (e.Children.Count()));

There is, however, no way to tell the compiler "just copy all of the properties across explicitly."

like image 39
Reed Copsey Avatar answered Nov 12 '22 19:11

Reed Copsey


There are several ways that you could accomplish this but they all are going to be nightmares.

1.) Overload a constructor and copy all of the values there (however that is what you are trying to get away from.

2.) Use reflection to copy the properties over (many bad side effect, not recommended)

3.) USE THE DECORATOR PATTERN. It looks like you added values to the original class so I think this would be the perfect time to use a decorator. This would also make it so that as properties are added they aren't missed. It would break the compile, however this solution isn't perfect if the object being decorated is sealed.

like image 1
Jerod Houghtelling Avatar answered Nov 12 '22 19:11

Jerod Houghtelling