【问题标题】:Linq - getting a value from a stringLinq - 从字符串中获取值
【发布时间】:2012-04-06 07:32:45
【问题描述】:

关于 SO 的第一个问题 - 我已经阅读了很多次,所以有时间在社区中深入了解一下!

我首先从 Linq 查询中获取一行:

var relationshipDetails = (from p in dc.tbl_ClientRelationships
                           where p.ID == relationship_id
                           select p).FirstOrDefault();

然后我查看一个字符串列表 (_cols),它是已知的列名(以及表单项名称),如下所示:

foreach (string c in _cols)
    {
      if (relationshipDetails.GetType().GetProperty(c).GetValue(relationshipDetails, null).ToString() != null)
        {
           setValue(relationshipDetails.GetType().GetProperty(c).GetValue(relationshipDetails, null).ToString(), c);
         }
     }

setValue() 方法基本上将返回的值分配给 web 控件(并且具有确定类型以及应如何分配等的逻辑。)

我的问题是,有没有更好的方法从已知属性值中获取 Linq 对象的值? 它适用于某些形式,但最近刚刚在我身上炸毁!

否则,我很想回到旧方法或从 DAL 返回 DataRow,然后轻松地按名称引用!

提前致谢, 标记

【问题讨论】:

  • C# 不会“炸毁”,它会引发异常。例外情况包括类型、消息和堆栈跟踪等信息。
  • 是的,确实需要更好的方法,您在循环中使用反射。那是一个昂贵的操作。等高手解答
  • 你为什么要积极尝试抛弃类型安全?
  • @Jon 我在线上收到System.NullReferenceException 以检查它是否为空。 IE。在我检查它是否为空之前它是空的。但是,如果我对可以正常工作的属性之一执行 response.write。
  • @RemarkLima:太好了。现在调试代码并找出表达式在以relationshipDetails. 开头的链中的哪个点计算为null

标签: c# asp.net linq webforms


【解决方案1】:

Linq to (Sql / Entities) 的最大优势之一(在我看来)是返回的对象是strongly-typed。您正在使用 LinqToX,然后使用反射来分配值,您基本上是在做老派 DataRow 所做的事情。

我不确定您为什么要尝试动态分配值。这绝对是XY Problem

【讨论】:

  • 一切都开始了!我以前从未完全使用过 Linq,所以认为是时候陷入困境了!像这样的信息是无价的。人们很容易被“Linq 无所不能!”的炒作所迷惑,而一些较旧的方法也可以做到。
【解决方案2】:

第一:

var relationshipDetails = (from p in dc.tbl_ClientRelationships
                          where p.ID == relationship_id
                          select p).FirstOrDefault();

Linq 查询是表示查询的对象,将它们与这些查询的结果分开并区别开来。在这种情况下,我建议改为:

var relationshipDetails = dc.tbl_ClientRelationships
                              .FirstOrDefault( p => p.Id == relationship_id);

现在,这会很慢:

foreach (string c in _cols)
{
  if (relationshipDetails.GetType().GetProperty(c).GetValue(relationshipDetails, null).ToString() != null)
    {
       setValue(relationshipDetails.GetType().GetProperty(c).GetValue(relationshipDetails, null).ToString(), c);
     }
 }

您可以轻松获得对反射成员的引用并减少开销,可能是这样的:(可能不是 100% 语法正确)

var properties = relationshipDetails.GetType().GetProperties();

foreach (string c in _cols)
{
    var currentProperty = properties.Single( p=> p.Name == c );

    if (currentProperty.GetValue(relationshipDetails, null) != null)
    {
        setValue(currentProperty.GetValue(relationshipDetails, null).ToString(), c);
    }
}

最后 - 你为什么要这样做?请详细说明您要做什么,以及为什么以类型安全的命名方式引用列,即:

relationshipDetails.Id = ...
relationshipDetails.SomethingElse = ...
relationshipDetails.AnotherThing = ...

不适用于您的情况。

【讨论】:

  • 谢谢你或详细的回答,我现在试试。原因如下:标记有它的文本框、复选框、下拉列表等...控件,所有的名称都以数据库的列名为后缀。当表单加载时,它会循环访问 web 控件,并构建一个列名列表。然后可以使用这些来创建 SQL 更新和插入。并且在加载数据时,我有问题的列名,所以只需要将它们引用到查询的对象。听起来越来越像是我应该为此坚持旧数据行?
  • all with a name suffixed with the column name of the database 您是否可以将有关数据表的详细架构信息公开给加载您页面的任何人?如果这出现在代码审查中,我会强烈建议不要这样做。
  • 这听起来像是你出于某种原因试图重新创建FormViewmsdn.microsoft.com/en-us/library/fyf1dk77(v=vs.85).aspx
  • 它不是面向公众的应用程序,用户基本上已经知道架构,所以不用担心(至少在我看来)。 formview 可以工作,但是有很多字段需要覆盖,并且在标记上使用自定义标记我根据标记的值添加验证。然而,我可能走错了路——这是众所周知的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 2016-09-30
  • 2021-07-13
  • 1970-01-01
相关资源
最近更新 更多