实体框架查询 - 按特定顺序获取对象

发布于 2024-11-05 15:28:25 字数 345 浏览 1 评论 0原文

我有一个列表,指定数据库中多个对象的 ID。我想要获取一组对象,全部来自一个表,这些对象具有这些 ID 并将它们保持在精确的顺序,并且我希望它作为针对数据库的一个查询(而不是“N”个查询)执行。

例如,我有一个 ID 列表 {5, 3, 6, 9},我想取回具有这些 ID 的 Customer 对象列表并保持它们的顺序 { Customer(5, 'Bob'), Customer( 3,'JimBo'),客户(6,'乔'),客户(9,'杰克')}。

数据量足够小,我不介意在数据库查询后重新排序。我可以用大约 15 行干净的代码完成所有这些(包括手动重新排序),但我觉得应该有一个针对 EF 的一两行 LINQ 查询应该可以轻松完成此操作。

I have a List specifying the IDs of a number of objects in my database. I want to get the set of objects, all from one table, that have those IDs and keep them in that exact order, and I want it to execute as one query against the DB (not 'N' queries).

For example, I have a list of IDs {5, 3, 6, 9}, and I want to get back a list of Customer objects with those IDs and keep them in order { Customer(5, 'Bob'), Customer(3, 'JimBo'), Customer(6, 'Joe'), Customer(9, 'Jack') }.

The amount of data is small enough that I don't mind having to re-sort it after the DB query. I could do all of this in about 15 lines of clean code (including re-sorting by hand), but I feel like there should be a one- or two-line LINQ query against EF that should do this easily.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

☆獨立☆ 2024-11-12 15:28:25

我相信您在收到结果后需要执行订购。我可能会这样处理。

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 列表与查询结果的内存中连接将保留 ID 的顺序。

编辑:来自评论

我的蜘蛛侠在使用 Join 时感到刺痛
依赖于维护排序
命令。我想知道这是否是规定的
加入文档的属性(如果
未来可能不会改变
.NET 版本,例如
性能原因)。

我指出您http://msdn.microsoft.com/en-us/library /bb534675.aspx备注部分

连接保留了顺序
外部的元素,并且对于每个
这些元素的顺序
内部的匹配元素。

I believe you'll need to perform your ordering after you get the results. I would probably tackle it like this.

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;

The in-memory join of the list of IDs to the query result will preserve the ordering of the IDs.

Edit: From Comment

my spidey senses tingle at using Join
to rely on maintaining the sorted
order. I wonder if that's a stated
property of Join in documentation (if
not it could change in some future
version of .NET, such as for
performance reasons).

I point you to http://msdn.microsoft.com/en-us/library/bb534675.aspx, the Remarks section

Join preserves the order of the
elements of outer, and for each of
these elements, the order of the
matching elements of inner.

埋葬我深情 2024-11-12 15:28:25

我不认为整个事情可以在一个查询中完成,但在两个查询中很容易完成。一份在数据库中,一份在内存中。

第一个查询将仅选择具有指定 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();

I dont think whole thing can be done in one query, but it is easy to do it in two queries. One on DB and one in memory.

First query will select only customers with specified Ids:

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

Second will order them according to your list:

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

var customersList = customers.ToList();
⒈起吃苦の倖褔 2024-11-12 15:28:25

显然,您可以轻松获得一个对象列表,其中 ID 列表包含正在搜索的 ID。至于 orderby,我无法想到基于单个查询中的 ID 列表来执行此操作。但是,如果您有一种逻辑方法来指定原始 ID 的排序方式(如果不是随机的),那么您可以创建一个相等比较器函数,如下所示 此处

You can obviously get a list of objects where the ID list contains the ID being searched easily enough. As for the orderby, there is no way I can think of to do this based on a list of IDs in a single query. However, if you have a logical way of specifying how the original IDs were ordered (if not random) then you can create an equality comparer function as shown here

屌丝范 2024-11-12 15:28:25
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() 方法。

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;}
}

The ids could be yet another query to get the Ids from somewhere else, but order them as you want. Note that this is a Linqpad code, hence .Dump() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文