Nick Birke
Nick Birke

Reputation: 137

LINQ and web service cannot return anonymous types, and you cannot construct an object in a query?

  1. Web services cannot return an anonymous type.
  2. If you are building a LINQ query using classes through a datacontext... you cannot construct instances of those classes in a query.

Why would I want to do this? Say I want to join three "tables" or sets of objects. I have three items with a foreign key to each other. And say the lowest, most detailed of these was represented by a class that had fields from the other two to represent the data from those. In my LINQ query I would want to return a list of the lowest, most detailed class. This is one way I have decided to "join some tables together" and return data from each of them via LINQ to SQL via a WebService. This may be bad practice. I certainly do not like adding the additional properties to the lowest level class.

Consider something like this... (please ignore the naming conventions, they are driven by internal consideration) also for some reason I need to instantiate an anonymous type for the join... I don't know why that is... if I do not do it this way I get an error...

from su in _dataContext.GetTable<StateUpdate>()
                  join sfs in _dataContext.GetTable<SystemFacetState>()
                    on new { su.lngSystemFacetState } equals new { lngSystemFacetState = sfs.lngSystemFacetState }
                  join sf in _dataContext.GetTable<SystemFacet>()
                    on new { sfs.lngSystemFacet } equals new { lngSystemFacet = sf.lngSystemFacet }
                   join s in _dataContext.GetTable<System>()
                    on new { sf.lngSystem } equals new {lngSystem = s.lngSystem}
                  select new
                  {
                      lngStateUpdate = su.lngStateUpdate,
                      strSystemFacet = sf.strSystemFacet,
                      strSystemFacetState = sfs.strSystemFacetState,
                      dtmStateUpdate = su.dtmStateUpdate,
                      dtmEndTime = su.dtmEndTime,
                      lngDuration = su.lngDuration,
                      strSystem = s.strSystem
                  }
                  ).ToList();

Notice I have to build the anonymous type which is composed of pieces of each type. Then I have to do something like this... (convert it to a known type for transport via the web service)

result = new List<StateUpdate>(from a in qr select(new StateUpdate 
{
    lngStateUpdate = a.lngStateUpdate,
    strSystemFacet = a.strSystemFacet,
    strSystemFacetState = a.strSystemFacetState,
    dtmStateUpdate = a.dtmStateUpdate,
    dtmEndTime = a.dtmEndTime,
    lngDuration = a.lngDuration,
    strSystem = a.strSystem
}));

It is just awful. And perhaps I have created an awful mess. If I am way way off track here please guide me to the light. I feel I am missing something fundamental here when I am adding all these "unmapped" properties to the StateUpdate class.

I hope someone can see what I am doing here so I can get a better way to do it.

Upvotes: 0

Views: 521

Answers (2)

Trevor Pilley
Trevor Pilley

Reputation: 16393

You can create a 'dto' class which just contains the properties you need to return and populate it instead of the anonymous object:

public class Result
{
    public string lngStateUpdate
    {
        get;
        set;
    }

    ... // other properties
}

then use it like this:

from su in _dataContext.GetTable<StateUpdate>()
...
select new Result
{
    lngStateUpdate = su.lngStateUpdate,
    ... // other properties
}

Nitpick note - please ditch the Hungarian notation and camel casing for properties :)

Upvotes: 1

Nick Birke
Nick Birke

Reputation: 137

I think the answer is to create another object to serve as a DTO. This object would not be mapped to the data context and can contain fields that cross the mapped objects. This solves the problems of repetitive properties in the mapped objects, and allows for instantiation of the DTO class in the query as it is not mapped.

FYI: with respect to the problem with the join- I revisited that and I think I may have had the inner and outer components of the join switched around before.

Upvotes: 0

Related Questions