我正在将项目从使用标准数据库查询转移到使用EF和LINQ。我有一个表,有一些记录,我将用于构建如下所示的查询:
select * from client where city = ?
在我的原始表中,我将从表中提取客户端和城市来构建该查询。
上面的客户端和城市也可能是另一个表和/或字段。我如何使用EF和LINQ做同样的事情?这甚至是可能的,还是我必须构建一个单独的类来处理所有逻辑?
var query = from c in context.clients
where c.city == ?
select c;
编辑:这不是关于加入查询。这是关于构建动态查询。我不知道我什么时候运行该程序是否会查询城市,地址,甚至是“客户”表本身。它可能在另一张桌子上。我希望能够动态构建查询。
答案 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");
因此,您的Where
和OrderBy
谓词是在引擎盖下转换为表达式的字符串。
其次,如果你知道你的查询是什么,你可以使用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中看到这两个选项。