2011-05-04 41 views
6

我有一个列表,指定我的数据库中一些对象的ID。我想从一个表中得到一组对象,它们都有这些ID并保持它们的顺序,并且我希望它作为一个针对数据库的查询执行(不是'N'查询)。实体框架查询 - 按特定顺序获取对象

例如,我有一个ID列表{5,3,6,9},并且我想要返回带有这些ID的Customer对象列表,并按顺序保留它们{Customer(5,'Bob' ),客户(3,'JimBo'),客户(6,'Joe'),客户(9,'Jack')}。

数据量足够小,我不介意在数据库查询后重新排序数据量。我可以在大约15行干净的代码中完成所有这些工作(包括手动重新排序),但是我觉得应该有一行或两行LINQ对EF的查询,应该很容易做到这一点。

回答

3

我不认为整个事情可以在一个查询中完成,但它很容易在两个查询中完成。一个在DB上,另一个在内存中。

首先查询将只选择客户指定ID:

var customers = (from c in context.Customers 
       where itemIds.Contains(c.Id) 
       select c).AsEnumerable(); 

其次会根据您的列表命令他们:

var customers = from id in itemIds 
       join c in customers 
       on id equals c.Id 
       select c; 

var customersList = customers.ToList(); 
+0

谢谢。事实证明,AsEnumerable没有必要(我用SQL Profiler进行了检查),尽管我也认为它会是。我不得不说...我的spidey感觉在使用Join时依赖于维护排序的顺序。我想知道这是否是文档中Join的一个声明属性(如果不是这样,它可能会在.NET的某些未来版本中发生更改,例如出于性能原因)。 – pbarranis 2011-05-04 15:33:07

3

我相信在获得结果后您需要执行您的订购。我可能会这样解决它。

var efQuery = /* your query here */.AsEnumerable(); // force evaluation 
var orderedResult = from id in idList // { 5, 3, 6, 9 } 
        join item in efQuery 
        on id equals item.Id 
        select item; 

在内存中加入ID来查询结果列表中的将保留编号的顺序。

编辑:从评论

我的蜘蛛侠在用加入 依靠维持整理 为了检测刺痛。我想知道是否这是一个说明 加入文件的属性(如果 不是它可能会改变一些未来的 版本的.NET,如 性能的原因)。

我点你http://msdn.microsoft.com/en-us/library/bb534675.aspx,该备注部分

加入保留外的 元素的顺序,并为每个 这些元素,的 匹配元素的顺序内。

+0

感谢。事实证明,AsEnumerable没有必要(我用SQL Profiler进行了检查),尽管我也认为它会是。我不得不说...我的spidey感觉在使用Join时依赖于维护排序的顺序。我想知道这是否是文档中Join的一个声明属性(如果不是这样,它可能会在.NET的某些未来版本中发生更改,例如出于性能原因)。 – pbarranis 2011-05-04 15:34:29

+0

@pbarranis,休息简单。我更新了答案以解决订购文档。 – 2011-05-04 15:40:31

0

显然你可以得到一个对象列表,其中ID列表包含了被搜索的ID很容易的对象。至于orderby,根据单个查询中的ID列表,我无法想到这样做。但是,如果您有指定原始ID是如何有序的(如果不是随机的)的一个合乎逻辑的方式,那么你可以创建一个平等的比较器功能,如图here

-1
void Main() 
{ 
    List<Data> data = new List<Data>(); 
    data.Add(new Data{Id =1, Name = "ABC1"}); 
    data.Add(new Data{Id =2, Name = "ABC2"}); 
    data.Add(new Data{Id =3, Name = "ABC3"}); 
    data.Add(new Data{Id =4, Name = "ABC4"}); 
    data.Add(new Data{Id =5, Name = "ABC5"}); 

    var result = from d in data 
       let ids = new List<int>{3,4,5} 
       where ids.Any(i=> i == d.Id) 
       select d; 
    result.Dump();    
} 

// Define other methods and classes here 
class Data 
{ 
    public int Id{get;set;} 
    public string Name{get;set;} 
} 

的ID可能是另一个查询得到的ID从别的地方,但按照你的意愿命令它们。请注意,这是Linqpad代码,因此.Dump()方法。

+0

-1。不是关于订购,而是EF兼容。 – Euphoric 2011-05-04 14:25:19

+0

不知道为什么你会这样说,你可以让你喜欢的订单获得订单,并加入到订单中以获取客户。这将是一个查询。额外的代码用于测试。 – 2011-05-04 14:29:18