【问题标题】:In linq how dynamically pass table and column name在linq中如何动态传递表和列名
【发布时间】:2010-07-11 06:21:10
【问题描述】:

我想写一个动态 linq,我发送表和列名,这个查询返回表的最大行数。

SELECT ISNULL(MAX(intProductCode) + 1, 1) AS intProductCode FROM tblProductInfo

以上是我的 T-SQL 语法。我希望 linq 如何获得相同的输出

如果我写下面的语法得到相同的输出,但在这里我不能设置 表和列名

this.Context.tblProductInfos.Max(p=>p.intProductCode)

如何在 linq 上设置表名和列名,返回该表的最大行数。

【问题讨论】:

  • 问一个 linq-to-sql 的问题,接受一个 linq-to-sql 的答案,然后(两年后)在 cmets 中询问一个 linq-to-entity 的问题,这种形式很糟糕另一个答案,并根据 cmets 接受该答案。最好将单独的问题作为单独的问题提出。

标签: .net linq linq-to-sql linq-to-objects


【解决方案1】:

LINQ 不能解决所有问题。当然,您可以查询数据上下文以获取所有这些信息,但您将要做很多工作(反射或映射,以及构建Expression),只是为了让 sql 生成器反转 一切 以取回 TSQL。仅构建 TSQL(确保将表/列名称列入白名单以防止注入)并使用ExecuteQuery 会更简单很多

例如:

string tsql = string.Format(
      "SELECT ISNULL(MAX([{0}]) + 1, 1) AS [{0}] FROM [{1}]",
       colName, tableName);

int max = dataContext.ExecuteQuery<int>(tsql).First();

还有;如果intProductCodeIDENTITY,您可能需要查看IDENT_CURRENT(tableName),它MAX 更高效

【讨论】:

  • Marc Gravell 如何在 linq.SELECT IDENT_CURRENT ('tableName') AS Current_Identity 中使用此 sql 语法。我用你的语法替换字符串 tsql 但它不起作用显示错误消息“指定的转换无效。”
  • IDENT_CURRENT 返回decimal, IIRC。试试SELECT CAST(IDENT_CURRENT('tableName') as int) as Current_Identity
  • Marc Gravell 感谢您的回复,在 EF(实体框架)中没有方法 ExecuteQuery(),请您告诉我如何在 EF 中执行您的 sql 语法。谢谢大家
  • @shamim SqlQuery ?
【解决方案2】:

给你:

int GetMax<T>(DataContext dc, Expression<Func<T, int>> selector)
{
  int result = dc.GetTable<T>().Max(selector);
  return result;
}

这样称呼:

int maxId = GetMax<Customer>(myDC, c => c.CustomerId);

另一方面,您可以只使用数据库中的 IDENTITY 列。这样您就不必 +1,也不必处理来自多个连接的冲突。

【讨论】:

  • David B 感谢您的回复,请告诉我如何在您的语法中设置 where,假设要设置 WHERE City='Berlin'。
【解决方案3】:

据我了解,您在这里并不需要任何动态 linq。

您应该停止考虑 SQL 魔术字符串,如表名和列名。 L2S 允许您以强类型的方式编写查询。检查您已经编写的代码。

this.Context.tblProductInfos.Max(p=>p.intProductCode)
  1. tblProductInfos 实际上是一个强类型的“表名”
  2. p=&gt;p.intProductCode 是获取“列名”的表达式

一切都很好,很清晰。不需要魔术字符串。这就是 ORM 的用途。

【讨论】:

  • 我需要一个通用的方法来返回表的最大行数。我需要调用这个方法。
  • 您已经为所有 IEnumerables 提供了此方法。为什么你认为Helper.Max("tableName", "columnName") 语法比'context.TableName.Max(x=>x.ColumnName)' 更好?
  • 这里的问题是,如果您在编译时不知道表名/列名,那么发布的代码将无济于事。
猜你喜欢
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 2019-12-04
  • 2020-03-15
  • 2020-08-01
  • 1970-01-01
相关资源
最近更新 更多