LINQ具有匿名类/属性

时间:2011-07-27 17:11:32

标签: c# linq entity-framework

我正在将项目从使用标准数据库查询转移到使用EF和LINQ。我有一个表,有一些记录,我将用于构建如下所示的查询:

select * from client where city = ?

在我的原始表中,我将从表中提取客户端和城市来构建该查询。

上面的客户端和城市也可能是另一个表和/或字段。我如何使用EF和LINQ做同样的事情?这甚至是可能的,还是我必须构建一个单独的类来处理所有逻辑?

var query = from c in context.clients
            where c.city == ?
            select c;

编辑:这不是关于加入查询。这是关于构建动态查询。我不知道我什么时候运行该程序是否会查询城市,地址,甚至是“客户”表本身。它可能在另一张桌子上。我希望能够动态构建查询。

5 个答案:

答案 0 :(得分:0)

如果您的表由外键连接,您可以使用LINQ访问另一个表中的值,如下所示。 (我通过假设存在“地址”表并且客户端表具有外键来扩展您的示例。)

var query = from c in context.clients
            where c.address.city == ?
            select c;

编辑:(试图理解您的原始问题和后续评论......)

你问的是你能做这样的事吗?

string cityName = "Los Angeles"; // Could be a parameter, etc.

var query = from c in context.clients
            where c.city == cityName
            select c;

或者,从你的问题更进一步,可能是这样的:

string cityName = (from c in context.cities
                   where c.id == 5
                   select c.name).FirstOrDefault();

var query = from c in context.clients
            where c.city == cityName
            select c;

由于它是一个IQueryable,你可以随时添加其他条件。

if (someCondition)
{
    query = from q in query
            where q.someField >= conditionValue
            select q;
}

或者其他什么。在实际需要结果之前,实际上不会评估/执行查询表达式树。

答案 1 :(得分:0)

您可以编写GalacticCowboy提供的查询,如

var query = from c in context.clients
        join add in context.Addresses on c.AddressID equals add.AddressID
        where addr.city == ?
        select c;

两个查询都会生成内连接,性能没有差别。唯一的区别是如果Address对于客户端是可选的,则c.address.City将在没有地址的客户端上抛出异常,而此查询将返回空枚举

答案 2 :(得分:0)

如果您真的想在运行时构建查询,那么可以使用几个基于linq的解决方案 - 您可以在运行时将代码编译为临时程序集,也可以使用其中一个MS示例中的DynamicLinq。 / p>

有关详细信息,请参阅以下内容中的问题和解答:How to create LINQ Query from string?

答案 3 :(得分:0)

我认为您可以采取一些方法。

首先,您可以查看Dynamic LINQ library(另请参阅David Fowler对其的更新here)。使用这种方法,您可以像这样编写LINQ查询:

var results = Context.Clients
                .Where("city=='Los Angeles'")
                .OrderBy("address");

因此,您的WhereOrderBy谓词是在引擎盖下转换为表达式的字符串。

其次,如果你知道你的查询是什么,你可以使用PredicateBuilder这样的库,但不确定你是否会在一个或多个字段上查询,如下所示:

var predicate = PredicateBuilder.True<Clients>();
foreach(var criteria in searchCriteria) {
  if (criteria.Key=="city"){
    predicate = predicate.And(c => c.city==criteria.Value);
  } else if (criteria.Key=="address"){
    predicate = predicate.And(c => c.address==criteria.Value);
  }
}
var results = Context.Clients.Where(predicate);

第三,也许最困难的是构建自己的表达式树。这绝对需要最多的代码(起初它有点深),但它非常非常强大。来自MSDN的这个example提供了一个很好的演练,你可以做些什么(并且可能比我在这里做的更简洁一点)。

所以,基本上,你有几个选择。动态LINQ库似乎是最容易使用的,但我从来没有使用它,所以我不能确定它的工作原理和可靠性。如果有帮助的话,动态LINQ库还有一个NuGet包。

祝你好运。希望这有帮助!

答案 4 :(得分:0)

如果要在Entity Framework中构建动态查询,可能会遇到尝试动态构建表达式树的麻烦。但是,实体框架为您提供了一些其他选项。

首先,EntityObject有一些额外的对象服务方法,它们已经允许你构建一个字符串并将其直接传递给许多谓词,包括Where:

c.Customers.Where("City = 'London'");

如果您需要构建更大的查询,包括动态设置查询源,请考虑使用EntitySQL。例如,使用EntitySQL,您可以使用简单的字符串解析并生成如下代码:

string entitySQL = "SELECT VALUE c FROM Customers AS c WHERE c.Address.City = 'Seattle';";
ObjectQuery<Customer> query = context.CreateQuery<Customer>(entitySQL);

您可以在Entity Framework Query Samples中看到这两个选项。