如何使用 LINQ 和变量动态查询数据库?
Posted
技术标签:
【中文标题】如何使用 LINQ 和变量动态查询数据库?【英文标题】:How to dynamically query the database using LINQ and a variable? 【发布时间】:2020-07-13 18:00:49 【问题描述】:我有一个包含 100 列的数据库表,标记为 D1、D2、D3 等等,直到 100。
在我的方法 (ASP.NET MVC) 中,我需要检查这些列是否为空,然后再将它们显示在我的视图中的表中。 我真的不想这样做:
if(db.Datatable.Select(x=>x.D1).FirstOrDefault() != null)
//do code
if(db.Datatable.Select(x=>x.D2).FirstOrDefault() != null)
//do code
if(db.Datatable.Select(x=>x.D3).FirstOrDefault() != null)
//do code
那将是 100 个 if 语句,而且看起来很糟糕。所以我在这里开始这段代码:
for(int i = 1; i < 100; i++)
var dbField = "D" + i; //D1,D2,D3....
var currField = db.Datatable.Select(x => x.dbField).FirstOrDefault();
//here i would add the value (0 for null, 1 for data) to an array, which i would handle in the view
除了 LINQ/C# 不喜欢这个。它显然会在 Select 语句中的 dbField 上引发错误。您不能只设置 .Select(x=x.variable)。我已阅读有关创建您自己的 lambda 表达式树和构建自定义动态查询的内容,关于如何执行此操作的任何想法?如何自定义为 Select 语句创建字段名称?谢谢。
【问题讨论】:
记录是什么意思?这是否引用任何给定行中的行或列值 我的意思是列,对不起。编辑原帖 我不确定FirstOrDefault
是否按照您的想法行事(或者您需要什么不清楚)。它应该返回例如的值D1
来自第一行 - 您只是想检查第一行是否有列的值吗?
嗯,你为什么要这样做?这将在功能上执行单个 sql 查询以获取第一条记录,然后在循环中获取列 x。这意味着如果您有 1000 列,它会执行数据库选择以获取每列的值,但全部用于同一记录。更好的设计是获取 整个 第一条记录,然后遍历属性并为每个属性执行 X。
var record = db.Datatable.First(); if(record.D1 != null) ... if(record.D2 != null) ....
【参考方案1】:
没有理由重复从同一个不变集合中获取第一个元素。简单地从集合中取出第一个元素,然后使用检索到的对象:
var element = db.Datatable.FirstOrDefault();
这已经极大地简化了您的代码并且提高了性能(因为您不需要为每个属性遍历集合):
if(element.D1 != null)
//do code
// and so on...
目前还不清楚为什么您需要确定每个字段都包含一个非空值。您从未发布任何显示您打算如何使用这些值的代码。
//here i would add the value (0 for null, 1 for data) to an array, which i would handle in the view
通常,最好确保您的视图可以处理空值,因为这意味着您无需担心在某个值为空时执行代码。
如果这是不可能的,那么将null
值简单地转换为默认的非空值仍然更容易。这意味着您仍然不必担心空值(在转换它们之后),因为您将不再有任何空值。
一个简单的方法是使用空合并运算符,例如
var firstName = element.D1 ?? String.Empty;
这确保null
值被默认值替换(您可以指定,我只是在这里选择了一个空字符串,但您可以选择任何您想要的)。
另请注意,您甚至不需要对不可为空的值(例如 int
)执行此操作,因为这些值会自动默认为 0
。
//here i would add the value to an array
为什么使用数组而不是对象?目前尚不清楚为什么您不喜欢手动处理每个属性(及其值)而不是自己传递对象,这显然是更好的 OOP 传递数据的方式。
同时想要手动处理所有数据并且不想必须处理所有这些数据是矛盾的。
【讨论】:
【参考方案2】:我认为,如果您更准确地解释您的想法,我们将能够更好地帮助您。
当我看到你的代码时,我推断你的表在你的视图中将只显示一条带有他适当的属性/列的记录。如果你想这样做,没关系。
另一方面,根据列数迭代表是一个坏主意,因为您正在耦合两个抽象级别。我的意思是你的 MVC 方法不应该知道列的数量,这就是你对“for(int i = 1; i
我认为你把问题从错误的角度交给了我。
【讨论】:
以上是关于如何使用 LINQ 和变量动态查询数据库?的主要内容,如果未能解决你的问题,请参考以下文章