【问题标题】:What is "it" in Entity Framework实体框架中的“它”是什么
【发布时间】:2011-07-17 07:27:50
【问题描述】:

如果之前有人问过这个问题,但我的任何搜索中都没有出现“它”,请原谅我。我有两个数据库表 Person 和 Employee 建模一个 Table-per-Type(例如 Employee is-a Person)。在我的 edmx 设计器中,我定义了一个实体 Employee,它将每列映射到它们各自的基础表(例如,姓名 -> 人员、工资 -> 员工)。

“it”允许我在 LINQ 表达式中做这样的事情:

context.Employees.Where("it.Name LIKE 'M%' AND it.Salary > 1234")

是否有任何好的链接来解释我可以期望“它”如何表现?我认为这不是通用的 LINQ 事物,它在某种程度上特定于实体框架。

编辑 0: 为 ObjectContext 生成的 C# 代码如下:

public partial class TestObjectContext : ObjectContext
{
  // lots of boilerplate removed for clarity

  public ObjectSet<Employee> Employees
  {
    get
    {
      if ((_Employees == null))
      {
        _Employees = base.CreateObjectSet<Employee>("Employees");
      }
      return _Employees;
    }
  }
}

【问题讨论】:

  • 看起来它指的是对象本身(在本例中为员工)。
  • 你从哪里得到这个的?提供一些上下文代码...
  • 即使在这种简单的情况下,“它”在生成 SQL 时也是两个不同的表。如果我在表达式中加入一些连接(或包含),我想知道它是如何设计的。
  • @Kris 上下文对象是 EDMX 设计器生成的默认对象(即它是一个 ObjectContext 对象)。似乎 ObjectContext 上的所有 ObjectSet 属性都具有这种有趣的“它”特性。

标签: c# linq entity-framework


【解决方案1】:

it 是当前ObjectQuery 命令的默认别名。查询生成器方法请参考documentation,尤其是别名部分:

查询生成器方法按顺序应用以构造累积查询命令。这意味着当前 ObjectQuery 命令被视为应用当前方法的子查询。

在查询构建器方法中,您使用别名来引用当前的 ObjectQuery 命令。默认情况下,字符串“it”是表示当前命令的别名,如下例所示:

int cost = 10;
// Return Product objects with a standard cost
// above 10 dollars.
ObjectQuery<Product> productQuery =
    context.Products
           .Where("it.StandardCost > @cost", new ObjectParameter("cost", cost));

当您设置 ObjectQuery 的 Name 属性时,该值将成为后续方法中的别名。以下示例通过将 ObjectQuery 的名称设置为“product”,然后在后续的 OrderBy 方法中使用此别名来扩展前一个示例:

// Set the Name property for the query and then 
// use that name as the alias in the subsequent 
// OrderBy method.
productQuery.Name = "product";
ObjectQuery<Product> filteredProduct = productQuery.OrderBy("product.ProductID");

【讨论】:

  • 谢谢,@BrokenGlass。我确实注意到(在看到您的回复并使用我的代码之后)每次返回新的 QueryObject 时 Name 都会恢复为“it”:它并不总是流向后续方法。 var objectQuery = context.Employees.Where("it.Name LIKE 'M%'"); objectQuery.Name = "e"; objectQuery = objectQuery.Where("e.Salary
【解决方案2】:

您说的是Dynamic LINQ 库。

如果您安装了 VS 2008,您可以在以下位置找到详细的 API 文档

<path to vs2008>\Samples\1033\CSharpSamples\LinqSamples\DynamicQuery\Dynamic Expressions.html

或从here下载

这是Scott Gu's article on Dynamic LINQ

这是Dynamic Expressions.html 文件的摘录。

当前实例

当解析带有单个未命名参数的 lambda 表达式时,未命名参数的成员自动在表达式字符串的范围内,并且可以使用关键字 it 整体引用未命名参数给出的当前实例。例如,

customers.Where("Country = @0", country);

等价于

customers.Where("it.Country = @0", country);

IQueryable 扩展方法都将其表达式参数解析为具有单个未命名参数的 lambda 表达式。

动态 Lambda 调用

表达式可以通过动态 lambda 调用引用其他动态 lambda 表达式。动态 lambda 调用由引用 System.Linq.Expressions.LambdaExpression 实例的替换变量标识符和参数列表组成。提供的参数必须与给定动态 lambda 表达式的参数列表兼容。

下面解析两个独立的动态 lambda 表达式,然后通过动态 lambda 调用将它们组合成一个谓词表达式:

Expression<Func<Customer, bool>> e1 = 
    DynamicExpression.ParseLambda<Customer, bool>("City = \"London\"");
Expression<Func<Customer, bool>> e2 =
    DynamicExpression.ParseLambda<Customer, bool>("Orders.Count >= 10");
IQueryable<Customer> query =
    db.Customers.Where("@0(it) and @1(it)", e1, e2);

当然可以以这种方式组合静态和动态 lambda 表达式:

Expression<Func<Customer, bool>> e1 =
    c => c.City == "London";
Expression<Func<Customer, bool>> e2 =
    DynamicExpression.ParseLambda<Customer, bool>("Orders.Count >= 10");
IQueryable<Customer> query =
    db.Customers.Where("@0(it) and @1(it)", e1, e2);

上面的例子都具有相同的效果:

IQueryable<Customer> query =
    db.Customers.Where(c => c.City == "London" && c.Orders.Count >= 10);

【讨论】:

  • 不,他说的不是这个
  • 我发现“它”指的是当前实例(例如,处理 IQueryable 时的 T 实例。)动态表达式链接看起来有点深奥,我认为“它”可能更常见。
  • @BrokenGlass 包含了文档的摘录。希望它澄清:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多