0

The scenario is like this: - EF stored procedure returns 5 columns as DataResult - All I need is 3 columns, so I coded

var data = (from i in db.GetDataResult()
               select new DataResult
                 {
                   prop1 = i.prop1,
                   prop2 = i.prop2,
                   prop3 = i.prop3,
                     }).ToList();
  • Without hard coding string names, I would like to get the names of the selected columns, that is prop1, prop2, and prop3.

How to achieve this programmatically?

usefulBee
  • 9,250
  • 10
  • 51
  • 89
  • `typeof(DataType).GetProperties().Where(p => p.Name.Contains("something")).Select(p => p.Name)` will return the names of all properties containing "something". You can use that `Where()` clause to filter on anything. Instead of `select new DataResult`, you can use an anonymous object that just contains the fields you're looking for. See http://stackoverflow.com/questions/3645494/how-can-anonymous-types-be-created-using-linq-with-lambda-syntax for example. – Steve May 23 '14 at 18:31
  • If I select anonymous, I get the error that can't convert anonymoustype to IList or IEnumerable. But what then would be the benefit of using anonymous over specifying the type? – usefulBee May 23 '14 at 18:49
  • It is working on anonymous type as well, `var s = x.GetType().GetProperties().Where(p => p.Name.Contains("something")).Select(p => p.Name).FirstOrDefault();` – sallushan May 23 '14 at 19:45

2 Answers2

1

As outlined by Steve, the Where() can be used to filter:

List<string> names = GetDesiredListOfNamesSomehow();
var props = typeof( DateTime ).GetProperties()
       .Where( i => names.Contains( i.Name ) ).Select( i => i.Name );
foreach (var prop in props)
{
    Console.WriteLine("Prop Name: " + prop);
}

However if you know the names to filter, you do not need to request the names. So I assume you are trying to get the actual properties themselves:

var props = typeof( DateTime ).GetProperties().Where( i => names.Contains( i.Name ) );
foreach (var prop in props)
{
    Console.WriteLine("{0}, Type {1}", prop.Name, prop.PropertyType);
}
John Arlen
  • 6,539
  • 2
  • 33
  • 42
  • But that still will require writing the property names by hand in advance as strings - as you did in new string[] {"Date", "Day", "DayOfWeek"}; However, what I am looking for is to get the names of prop1, prop2, and prop3 from var data, as mentioned in the main example in order to avoid messing with strings. – usefulBee May 23 '14 at 20:02
  • 1
    How do you plan to identify *which* properties you want? – John Arlen May 23 '14 at 20:17
  • That is what I was trying to accomplish. The first step was to select or filter only the columns/properties which I need from a DB stored Proc, as I did in the second code example in the main post...Second, I was hoping that using reflection or any other technique to get the names of the properties/columns which I selected/filtered in step one. – usefulBee May 23 '14 at 20:27
  • The hard-coded strings above were an example. Use whatever source (database or whatever) as inputs. – John Arlen May 23 '14 at 20:38
  • The issue is that the source, in this case the stored proc, is returning columns more than I need. Since I don't have much control of DB stuff, I wanted to use the data I got and filter the columns I need, then get the names of those filtered columns/properties. – usefulBee May 23 '14 at 20:53
  • 1
    I still don't understand; how can you filter first (using the column names) without knowing the names, and *then* get the column names? Are you not filtering which columns you want based on the column names? – klugerama May 27 '14 at 16:15
  • Neither do I, I don't understand. You say: _I wanted to use the data I got and filter the columns I need_. And so... you are the only one who knows what columns you need! – nlips May 27 '14 at 21:19
  • @klugerama and nlips, I don't know what so hard to understand about this. The code above is so clear. I selected properties/columns without hard coding strings - this is done. Now, how to get the names of those selected properties - programmatically? – usefulBee May 28 '14 at 13:50
1

I think I understand. You are saying that you don't need the filter, you already have done that; you're wanting to get the mapped column name. First see this answer.

That said, based on @John Arlen's answer:

foreach (var prop in data[0].GetType().GetProperties())
{
    Console.WriteLine("{0}, Type {1}", prop.Name, prop.PropertyType);
}

The problem here is that this should normally give you:

prop1, *some type*
prop2, *some type*
prop3, *some type*

The confusion is that you are somehow specifying columns before you know the names, and yet in your code example you are using the column names. The columns that you specify should match the column names; prop1 in your code should correspond to the column prop1 in the data source. You were implying that you wanted to filter which columns to get (and which columns to not get) based on the column names.

So this is assuming that you already know beforehand which columns you want, based on some other (unspecified) criteria; that is, if you know that you are getting prop1, prop2, and prop3 but not propX or propY. Obviously you can't get the column/property names before you filter columns/properties if you don't know the names.

Edit

It occurs to me that you may be wanting to determine which fields are getting filled, and which are not. This might work if you know that none of the fields are null:

foreach (var prop in data[0].GetType().GetProperties())
{
    if (prop.GetValue(data[0], null) != null)
        Console.WriteLine("{0}, Type {1}", prop.Name, prop.PropertyType);
}

Edit 2

Also see this SO question.

Community
  • 1
  • 1
klugerama
  • 3,312
  • 19
  • 25
  • Thanks for your persistence. data[0].GetType().GetProperties() based on null or not null that is exactly what I needed - I didn't see that part in John's answer. And you are correct that I knew beforehand which columns I want based on "unspecified" criteria - I thought that was clear - my mistake. And regarding the example, I assume that you know that prop1, 2, and 3 are not hard coded strings, or in other words, you can grab them using intellisense. Thanks for the helpful links as well. – usefulBee May 29 '14 at 02:42