Nik*_*nte 36 c# linq-to-entities entity-framework
如何以随机顺序返回匹配的实体?
要明确这是Entity Framework的东西和LINQ to Entities.
(航空代码)
IEnumerable<MyEntity> results = from en in context.MyEntity
where en.type == myTypeVar
orderby ?????
select en;
Run Code Online (Sandbox Code Playgroud)
谢谢
编辑:
我尝试将其添加到上下文中:
public Guid Random()
{
return new Guid();
}
Run Code Online (Sandbox Code Playgroud)
并使用此查询:
IEnumerable<MyEntity> results = from en in context.MyEntity
where en.type == myTypeVar
orderby context.Random()
select en;
Run Code Online (Sandbox Code Playgroud)
但我得到了这个错误:
System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Guid Random()' method, and this method cannot be translated into a store expression..
Run Code Online (Sandbox Code Playgroud)
编辑(当前代码):
IEnumerable<MyEntity> results = (from en in context.MyEntity
where en.type == myTypeVar
orderby context.Random()
select en).AsEnumerable();
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 50
这样做的一种简单方法是按顺序排序,Guid.NewGuid()然后在客户端进行排序.你可能能够说服EF在服务器端做一些随机的事情,但这并不一定简单 - 使用"随机数排序"这样做显然已被打破.
要在.NET端而不是在EF中进行排序,您需要AsEnumerable:
IEnumerable<MyEntity> results = context.MyEntity
.Where(en => en.type == myTypeVar)
.AsEnumerable()
.OrderBy(en => context.Random());
Run Code Online (Sandbox Code Playgroud)
最好将无序版本放入列表然后随机播放.
Random rnd = ...; // Assume a suitable Random instance
List<MyEntity> results = context.MyEntity
.Where(en => en.type == myTypeVar)
.ToList();
results.Shuffle(rnd); // Assuming an extension method on List<T>
Run Code Online (Sandbox Code Playgroud)
除了其他任何东西之外,洗牌比排序更有效.有关获取适当实例的详细信息,请参阅我的随机性文章Random.Stack Overflow上有很多Fisher-Yates shuffle实现.
Dre*_*kes 37
Jon的回答是有帮助的,但实际上你可以让DB使用Guid和Linq to Entities 进行排序(至少,你可以在EF4中):
from e in MyEntities
orderby Guid.NewGuid()
select e
Run Code Online (Sandbox Code Playgroud)
这会生成类似于的SQL:
SELECT
[Project1].[Id] AS [Id],
[Project1].[Column1] AS [Column1]
FROM ( SELECT
NEWID() AS [C1], -- Guid created here
[Extent1].[Id] AS [Id],
[Extent1].[Column1] AS [Column1],
FROM [dbo].[MyEntities] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[C1] ASC -- Used for sorting here
Run Code Online (Sandbox Code Playgroud)
在我的测试中,使用Take(10)生成的查询(转换为TOP 10SQL),查询在具有1,794,785行的表中始终在0.42和0.46秒之间运行.不知道SQL Server是否对此进行了任何类型的优化,或者是否为该表中的每一行生成了GUID .无论哪种方式,这将比将所有这些行放入我的进程并尝试在那里排序要快得多.
Mic*_*tov 26
简单的解决方案是创建一个数组(或a List<T>),然后将其索引随机化.
编辑:
static IEnumerable<T> Randomize<T>(this IEnumerable<T> source) {
var array = source.ToArray();
// randomize indexes (several approaches are possible)
return array;
}
Run Code Online (Sandbox Code Playgroud)
编辑:就个人而言,我发现Jon Skeet的答案更优雅:
var results = from ... in ... where ... orderby Guid.NewGuid() select ...
Run Code Online (Sandbox Code Playgroud)
当然,你可以采用随机数发生器代替Guid.NewGuid().
| 归档时间: |
|
| 查看次数: |
36384 次 |
| 最近记录: |