5

I have requirement to dynamically add property values based on column values. Current I am creating object as below:

while (rd.Read())
 {
   list.Add(new DeviceModelInfo()
    {
       ID = rd.GetGuid("ID"),
       Manufacturer = new Manufacturer()
       {
         ID = rd.GetGuid("ManufacturerID"),
         Name = rd.GetString("ManufacturerName"),
         ManufacturerType (ManufacturerEnum)rd.GetInt32("ManufecturerType")
       },
       Model = rd.GetString("Model"),
       IMEI = rd.GetString("IMEI")
    });
 }

But I need to check if IMEI column is available or not in DataReader but when I am using if else then its giving syntax error I want to add IMEI if its available in DataReader how can I achieve that?

 if (rd.GetName(i).Equals("IMEI", StringComparison.InvariantCultureIgnoreCase))
    IMEI = rd.GetString("IMEI")
Jeric Cruz
  • 1,899
  • 1
  • 14
  • 29
Pankaj Bhatia
  • 202
  • 1
  • 11

3 Answers3

3

I'm assuming i is already a variable somewhere which has the number of the column that will be the IMEI if it's available. If that's not the case, see the end of the answer.

You can't use an if statement in an object initializer. What you could do is separate it out into a separate statement:

while (rd.Read())
{
    var device = new DeviceModlInfo
    {
        ID = rd.GetGuid("ID"),
        Manufacturer = new Manufacturer()
        {
           ID = rd.GetGuid("ManufacturerID"),
           Name = rd.GetString("ManufacturerName"),
           ManufacturerType (ManufacturerEnum)rd.GetInt32("ManufecturerType")
        },
        Model = rd.GetString("Model");
    };
    if (rd.GetName(i).Equals("IMEI", StringComparison.InvariantCultureIgnoreCase))
    {
        device.IMEI = rd.GetString("IMEI");
    }
    list.Add(device);
}

Alternatively, you could use the conditional ?: operator to assign one value or another to IMEI based on a condition:

while (rd.Read())
{
    list.Add(new DeviceModelInfo
    {
       ID = rd.GetGuid("ID"),
       Manufacturer = new Manufacturer()
       {
           ID = rd.GetGuid("ManufacturerID"),
           Name = rd.GetString("ManufacturerName"),
           ManufacturerType (ManufacturerEnum)rd.GetInt32("ManufecturerType")
       },
       Model = rd.GetString("Model"),
       IMEI = rd.GetName(i).Equals("IMEI", StringComparison.InvariantCultureIgnoreCase))
            ? rd.GetString("IMEI") : null;
   });

}


If you actually don't know which column would be the IMEI, I'd probably write a separate method to check whether the column is present or not, just once. You'd then write (outside the loop):

int? imeiColumn = GetColumn(dr, "IMEI");

Then in your object initializer, write:

IMEI = imeiColumn != null ? dr.GetString(imeiColumn.Value) : null

Where GetColumn might look something like:

static int? GetColumn(DbDataReader reader, string name)
{
    for (int i = 0; i < reader.VisibleFieldCount; i++)
    {
        if (reader.GetName(i).Equals(name, StringComparison.InvariantCultureIgnoreCase))
        {
            return i;
        }
    }
    return null;
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

You can use this extension method:

public static bool ColumnExists(this IDataRecord dr, string ColumnName)
{
    for (int i=0; i < dr.FieldCount; i++)
    {
        if (dr.GetName(i).Equals(ColumnName, StringComparison.InvariantCultureIgnoreCase))
            return true;
    }
    return false;
}

Use:

while (rd.Read())
{
    if(rd.ColumnExists("IMEI"))
    // DO YOUR WORK
}

Another way using LINQ:

Only work with .NET 3.5 and above

 while (rd.Read())
 {
     if(Enumerable.Range(0, rd.FieldCount).Any(c => rd.GetName(c) == "IMEI"))
     // DO YOUR WORK
 }
Gaurang Dave
  • 3,956
  • 2
  • 15
  • 34
0

You can use conditional operator ?: to check whether IMEI column exist or not. If Column exist then get the value otherwise set IMEI value as No IMEI( whatever you like)

So change,

IMEI = rd.GetString("IMEI") //Inside list.Add(new DeviceModelInfo()..)

to

IMEI = rd.GetName(i).Equals("IMEI", StringComparison.InvariantCultureIgnoreCase) ? rd.GetString("IMEI"):"No IMEI"
Abhilash Ravindran C K
  • 1,818
  • 2
  • 13
  • 22