使用linq查询动态对象

时间:2017-11-30 19:43:58

标签: c# linq

我动态设置对象的类型 然后我想查询该对象

  int id = 123;
  dynamic b = 
    Convert.ChangeType(dataToCompareTo, Type.GetType(tableName));

 var values = (from item in (b)
                where item.Id == id
                select item).FirstOrDefault();

Linq不允许我这样做("不允许使用动态[..]源类型的查询表达式")。我不知道运行前的对象类型。

2 个答案:

答案 0 :(得分:3)

dynamic在这里使用是错误的。 ChangeType的返回类型为object。编译器无法在编译时知道类型是什么。如果您将b定义为var,编译器会将b视为object,并且不再了解它。

您的LINQ表达式似乎期望实现IEnumerable甚至IEnumerable<SomeType>的特定类型。在这种情况下,您必须将其强制转换为以下类型:

int id = 123;
var b = 
Convert.ChangeType(dataToCompareTo, Type.GetType(tableName));

IEnumerable<SomeType> c = b as IEnumerable<SomeType>;
if (c == null)
{
    ///this is where you handle the objects that aren't what you need them to be for the linq expression below
}
else
{
    var values = (from item in (c)
            where item.Id == id
            select item).FirstOrDefault();
}

答案 1 :(得分:1)

如果你想使用动态 - 你可以在这里做。假设您知道您的b变量是具有Id属性的某种类型的列表,但您不知道哪个,并且无论出于何种原因无法使用接口:

public class SomethingWithId {
    public int Id { get; set; }
}
// you have no idea what that is at runtime
object something = new List<SomethingWithId>() {new SomethingWithId() {Id = id}};

然后您可以像这样使用dynamic

object something = new List<SomethingWithId>() {new SomethingWithId() {Id = id}};
// cast to `IEnumerable<dynamic>`, this will always compile
// but of course might fail at runtime, as always with dynamic
// in your case that is (IEnumerable<dynamic>) Convert.ChangeType(dataToCompareTo, Type.GetType(tableName));
var b = (IEnumerable<dynamic>) something;
// run your query
var values = (from item in b
       where item.Id == id
       select item).FirstOrDefault();

那就是说 - 不要习惯用C#来做这些事情 - 它是强类型的语言,你不应该忽视它提供的好处。