使用实体框架在运行时动态选择列

时间:2014-01-13 06:09:31

标签: c# sql asp.net entity-framework formatexception

我有一个像这样的现有功能

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

该表有四列用于存储整数值,我使用上面的函数分别读取它们。

现在我将其转换为Entity Framework。

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

但上面的函数返回错误

  

输入字符串格式不正确

因为它返回列名本身。

我不知道如何解决这个问题因为我对EF很新。

任何帮助将不胜感激

谢谢

5 个答案:

答案 0 :(得分:2)

您必须尝试使用​​动态LINQ。详细信息为HERE

答案 1 :(得分:2)

这可能有助于解决您的问题:

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;
}

此方法现在适用于动态输入方法参数sCol

答案 2 :(得分:0)

您可以这样做:

Annualized_Revenue:= [Revenue_YTD]/COUNTROWS(DATESYTD('DIM_Time'[PK_Date]))*365

答案 3 :(得分:-1)

你可以使用Reflection,就像这样(没有经过测试的代码):

public string sFunc(string sCol , int iId)
{
  var row = TableRepository.Entities.Where(x => x.ID == iId);
  var type = typeof(row);
  var propInfo = type.GetProperty(sCol);

  if (propInfo != null)
  {
    string value = (string)propInfo.GetValue(row);

    return value;
  }

  return null;
}

答案 4 :(得分:-2)

不要将字符串列名作为参数传递,而是尝试传入lambda表达式,如:

sFunc(x => x.FirstColumnName, rowId);
sFunc(x => x.SecondColumnName, rowId);
...

这最终将为您提供列名称的​​智能感知,因此您可以避免在列名称输入错误时出现错误。

有关此内容的更多信息:C# Pass Lambda Expression as Method Parameter

但是,如果您必须保留相同的方法签名,即支持其他/遗留代码,那么您可以尝试这样做:

public string sFunc(string sCol , int iId)
{
    return TableRepository.Entities.Where(x => x.ID == iId).Select(x => (string) x.GetType().GetProperty(sCol).GetValue(x)});
}

您可能需要稍微调整一下,我没有快速测试方法。