c# - 是否可以使用“Array.IndexOf”或其他代码派生数据对数据库中的 EF 查询结果进行排序?
问题描述
以下代码有效,但需要先从数据库中获取结果:
// ID's by priority (arbitrary yet limited number; eg. 1 to 10 values)
var ids = new [] { 3, 1, 2 };
// Should return "item 3" if it exists, else "item 1", else "item 2"..
var firstItemByPriority = context.Items
.Where(i => ids.Contains(i.Id))
.ToList() // materialize DB results
.OrderBy(i => Array.IndexOf(ids, i.Id))
.FirstOrDefault(); // ie. TOP 1 / LIMIT 1 / First (by ordering)
有没有一种方法可以在生成的数据库查询中进行排序?(在手动编写 SQL 时,可以通过几种不同的方式构建。)
虽然上面的示例使用,但总体目标是按不在数据库中Array.IndexOf
的派生数据进行排序。使用 SQL Server 特定的扩展和/或第三方扩展是公平的。
解决方案
如果没有原始 SQL 查询,就无法有效地执行此操作,并且原始 SQL 查询不能与 EF6 中的 LINQ 查询组合,就像它们在 EF Core 中一样。但是用于此的 SQL 查询非常简单。所以是这样的:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
namespace Ef6Test
{
public class Item
{
public int Id { get; set; }
public String Name { get; set; }
}
public class Db : DbContext
{
public Db() : base("server=localhost;database=ef6Test;integrated security=true")
{ }
public DbSet<Item> Items{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Item>()
.ToTable("Items")
.Property(i => i.Id)
.HasColumnName("Id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
base.OnModelCreating(modelBuilder);
}
}
internal class Program
{
public static void Main(string[] args)
{
using (var db = new Db())
{
db.Database.Log = m => Console.WriteLine(m);
if (db.Database.Exists())
db.Database.Delete();
db.Database.Create();
for (int i = 0; i < 1000; i += 2)
{
var item = new Item() { Id = i, Name = $"Item{i}" };
db.Items.Add(item);
if (i % 100 == 0)
db.SaveChanges();
}
db.SaveChanges();
}
using (var db = new Db())
{
db.Database.Connection.Open();
db.Database.ExecuteSqlCommand("create table #ids(position int primary key, id int)");
var ids = new[] { 3, 1, 12, 5, 8, 10, 7};
var json = System.Text.Json.JsonSerializer.Serialize(ids);
var pIds = new SqlParameter("@ids", System.Data.SqlDbType.NVarChar, -1);
pIds.Value = json;
db.Database.ExecuteSqlCommand("insert into #ids(position,id) select [key], [value] from openjson(@ids)", pIds);
var sql = @"
select top (@count) i.*
from Items i
join #ids ids
on i.Id=ids.Id
order by ids.position
";
var pCount = new SqlParameter("@count", 3);
var results = db.Database.SqlQuery<Item>(sql,pCount).ToList();
foreach (var item in results)
{
Console.WriteLine(item.Id);
}
}
Console.WriteLine("complete");
}
}
}
输出
12
8
10
complete
推荐阅读
- python - 损失在 Keras ANN 的所有时期都变成“南”(回归)
- .net - 在 DataGridView 中单击一个复选框时如何切换所有选定行中的所有复选框
- android - 我的开关没有转到我的风格颜色
- axlsx - 如何在 axlsx 中使用聚合公式
- python - 使用开始和结束索引方法是实现二进制搜索的唯一方法吗?
- sharepoint - PowerApps - 发布后未触发 onChange,在编辑器应用预览中触发(F5)
- kubernetes - 在同一个 TF 脚本中使用多个 Terraform 提供程序(GCP 和 Kubernetes)创建资源
- python - 连接字符串而不打印到终端顶部
- amazon-web-services - 在 Amazon Redshift 中的物化视图上创建索引
- python-3.x - 如何在多处理python中为思路分配资源