views:

119

answers:

2

I am using Linq to Entities in a method and returning specific columns of data from the method. I don't know what type I'll be returning so I rigged it to return a List. If someone knows a better way than the way I rigged it, PLEASE let me know. See the code below.

After returning this data, I then need to iterate through the columns to get the column name and the value. I can see the string that the object has in it and it's JSON. It has "{ Column1 : Value1, Column2 : Value2 }". How can I iterate through to not just get the value, but get the name too...without using reflection?

Here's an example of the method I'm calling off to:

    public static List<object> GetDataSource(string QueryName)
    {
        MyEntity myEntity = new MyEntity();
        switch (QueryName)
        {
            case "FirstQuery":
                var s = (from x in myEntity.TableName
                         select new
                         {
                             Column1 = x.FirstColumn,
                             Column2 = x.SecondColumn
                         }).ToList();

                return s.Cast<object>().ToList();
        }
        return null;
    }
+3  A: 

Anonymous types are local scoped. You cannot use them outside the method they were defined in (besides resorting to a horrible grotty hack). Why not just define some domain class that will represent your data in a strongly typed manner:

public class Table
{
    public string Column1 { get; set; }
    public string Column2 { get; set; }
}

public static IEnumerable<Table> GetDataSource(string QueryName)
{
    MyEntity myEntity = new MyEntity();
    switch (QueryName)
    {
        case "FirstQuery":
            return from x in myEntity.TableName
                   select new Table
                   {
                       Column1 = x.FirstColumn,
                       Column2 = x.SecondColumn
                   };
    }
    return Enumerable.Empty<Table>();
}
Darin Dimitrov
Well I want to be able to return different types, so if I have a case "SecondQuery", I would need to be able to return class Table2 as well. Then there's still the issue of getting the column names by iterating through the returned data that I can't do without reflection.
DougJones
A: 

Hello,

I managed to implement the way you needed. It worked for me:

public class Table{
public string Column1 { get; set; }
public int Column2 { get; set; }}

 public static IEnumerable<T> GetDataSource<T>()
    {
        MyEntity myEntity = new MyEntity();

        if (typeof(T) == typeof(Table))
        {
            IQueryable<Table> query = from x in myEntity.Table1
                   select new Table
                   {
                       Column1 = x.TheColumn1,
                       Column2 = x.TheColumn2
                   };

           return query.ToList().Cast<T>();
        }
        if (typeof(T) == typeof(Table2))
        {
            IQueryable<Table2> query = from x in myEntity.Table2
                   select new Table2
                   {
                       TestColumn1 = x.TheColumn123,
                       TestColumn2 = x.TheColumn321
                   };

            return query.ToList().Cast<T>();
        }

        return Enumerable.Empty<T>();
    }

I haven't used the QueryName parameter, but you can always add it if there is more then one data sources that can IEnumerable.

Misha N.
Well this definitely looks better than my rigged List<object> return type, but with my GetDataSource I didn't need to know which type I would be returning. In this case, I'll have to call off to the method with the type (which I don't know), e.g. "GetDataSource<Table2>();". All I know ahead of time is the query name that I want to call.Also, how could I retrieve the column names (the properties of the Table classes) without using reflection?I'm probably just making this way too complicated, but I'm not sure how to simplify it.
DougJones
Hmm,to retrieve the property names form an object without reflection, not possible I believe. Although I don't have information about how your project is organized, even if you accomplish that I think that code will be difficult to read, track, change in future. From my point of view (actually Martin Fowler's in book Refactoring)for each method should be obvious what it does just by looking at it's name. So, if possible, I would create one method for each data source (QueryName) you have, without using one method and "hacks" to get results from that method.
Misha N.
The QueryName is stored in a string on the database or in xml or something. I can only retrieve it as a string. How can I dynamically declare call GetDataSource, sending that string QueryName as the Type? Basically, this: GetDataSource<"QueryName">(); If I could get that your example code would work for me. I'd still need to use reflection, but it would really be a fairly minor performance hit.
DougJones