迭代通过域模型上的linq查询返回的对象的属性和值

bde*_*ino 39 c# linq entity-framework telerik-open-access

我在关系数据库中有一个自定义实体,我已经通过域模型映射到CLR.因此,通过使用以下语句,我可以通过域模型上的LINQ查询将实体从我的数据库中提取到内存中,就像这样;

var inspection = (from i in dbContext.New_testinspectionExtensionBases
              where i.New_testinspectionId == currentInspection   
              select i).First();                         
Run Code Online (Sandbox Code Playgroud)

我需要访问此实体上的属性/字段,我需要能够确定属性/字段名称及其值.我想在内存中循环这些项,并将其名称和值写出到控制台.

我尝试使用这种方法,但无法弄清楚如何纠正语法(我也不确定GetProperties是否使用正确的方法,GetFields由于某种原因没有返回任何内容所以我认为这是要走的路)但它并不重要,因为我需要的是对值的读访问权;

var inspectionReportFields = inspection.GetType().GetProperties(); 
// I called this inspectionReportfields because the entity properties correspond to 
// form/report fields I'm generating from this data.

foreach (var reportField in inspectionReportFields)
{
    var value = reportField.GetValue();
    Console.WriteLine(reportField.Name);
    Console.WriteLine(value);
}
Run Code Online (Sandbox Code Playgroud)

在使用像EF或openaccess这样的域模型时,是否有更简单的方法来获取属性/字段值?如果没有,我会以正确的方式进行吗?最后,如果是这样,我如何修复值变量声明中的语法?

以下是域模型生成的代码中的一些示例字段/属性,供参考;

    private int? _new_systemGauges;
    public virtual int? New_systemGauges 
    { 
        get
        {
            return this._new_systemGauges;
        }
        set
        {
            this._new_systemGauges = value;
        }
    }

    private int? _new_systemAlarm ;
    public virtual int? New_systemAlarm 
    { 
        get
        {
            return this._new_systemAlarm;
        }
        set
        {
            this._new_systemAlarm = value;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Mic*_*eld 76

我假设您正在尝试定义一种通用的方法来"转储"对象,而不了解其结构.如果是这样,那么你就是正确的方式.您可以使用反射(GetType()以及关联的Type类方法)来检查对象并返回其信息.

GetFields()没有返回的原因是你可能没有提供正确的绑定标志.特别是,如果调用不带任何参数的重载,则只返回public字段; 如果你想要私人领域,你需要特别要求他们.

在您的情况下,GetFields(BindingFlags.NonPublic)将返回_new_systemGauges_new_systemAlarm字段,而GetProperties()将返回New_systemAlarmNew_systemAlarm属性.

您错过的另一个关键因素是您要获取的数据是类型元数据; 它定义了结构class,而不是任何特定的实例.如果您想知道特定实例的属性值是什么,您需要询问:

foreach (var prop in obj.GetType().GetProperties())
{
  Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(obj, null));
}
Run Code Online (Sandbox Code Playgroud)

如果您拥有PropertyInfo类型元数据中的一个元素,则可以在该类型的任何实例上请求该属性值.它不必与您最初使用的实例相同.例如:

var objs = somelist.Where(x => x.Id == 1);
foreach (var prop in objs.First().GetType().GetProperties())
{
  int x = 0;
  foreach (var obj in objs)
  {        
    if (prop.PropertyType.Name.Equals("Int32"))
    {
      int val = (int)prop.GetValue(obj, null);
      Console.WriteLine("Obj #{0}: {1} = 0x{2:x8}", x++, prop.Name, val);
    }
    else if (prop.PropertyType.Name.Equals("Decimal"))
    {
      int val = (decimal)prop.GetValue(obj, null);
      Console.WriteLine("Obj #{0}: {1} = {2:c2}", x++, prop.Name, val);
    }
    else
    {
      Console.WriteLine("Obj #{0}: {1} = '{2}'", x++, prop.Name, prop.GetValue(obj, null));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,您应该检查结果GetIndexParameters以查看属性是否已编入索引; 的null到参数GetValue实际上是指数值的阵列.

要转换您获得的值,您可以使用类型转换,或者如果您想要更灵活一些,请使用Convert类的方法.不同的是,例如,如果你有一个short属性,GetValue()将返回一个盒装短片,然后你就不能将它作为一个int; 你必须将它拆箱到short第一个.使用Convert.ToInt32()将执行所有必需的步骤,以int从任何可转换为整数的属性中获取值.

引用类型之间的转换更容易,因为您可以使用isas为此; 这些工作就像你期望的"反映"属性值一样.