Search code examples
c#sqlasp.netentity-frameworkformatexception

Dynamically select columns in runtime using entity framework


I have an existing function like this

public int sFunc(string sCol , int iId)
{
    string sSqlQuery = "  select  " + sCol + " from TableName where ID = " +  iId ;
    // Executes query and returns value in column sCol
}

The table has four columns to store integer values and I am reading them separately using above function.

Now I am converting it to Entity Framework .

public int sFunc(string sCol , int iId)
{
     return Convert.ToInt32(TableRepository.Entities.Where(x => x.ID == iId).Select(x => sCol ).FirstOrDefault());
}

but the above function returns an error

input string not in correct format

because it returns the column name itself.

I don't know how to solve this as I am very new to EF.

Any help would be appreciated

Thank you


Solution

  • This might help to solve your problem:

    public int sFunc(string sCol, int iId)
    {
        var _tableRepository = TableRepository.Entities.Where(x => x.ID == iId).Select(e => e).FirstOrDefault();
        if (_tableRepository == null) return 0;
    
        var _value = _tableRepository.GetType().GetProperties().Where(a => a.Name == sCol).Select(p => p.GetValue(_tableRepository, null)).FirstOrDefault();
    
        return _value != null ? Convert.ToInt32(_value.ToString()) : 0;
    }
    

    This method now work for dynamically input method parameter sCol.

    Update: This is not in context of current question but in general how we can select dynamic column using expression:

    var parameter = Expression.Parameter(typeof(EntityTable));
    var property = Expression.Property(parameter, "ColumnName");
    //Replace string with type of ColumnName and entity table name.
    var selector = Expression.Lambda<Func<EntityTable, string>>(property, parameter);
    
    //Before using queryable you can include where clause with it. ToList can be avoided if need to build further query.
    var result = queryable.Select(selector).ToList();