首页 > 解决方案 > 如何通过 EF6 将 SQLQuery 转换为 SortedList

问题描述

我有一个名为 Entity Framework 6 的类Materials,它在我的数据库中反映为具有相同名称的表。使用父参数,我需要从 SQL 查询返回一个排序的材料列表,以便我以后可以检查用户所做的编辑是否不会影响订单。我的 SQL 是一个如下所示的存储过程:

CREATE PROC [dbo].[GET_SortedMaterials](@FinishedGoodCode   VARCHAR(50))
AS

SELECT
     ROW_NUMBER() OVER (ORDER BY Component.Percentage_of_Parent DESC,Material.Material) AS _sortField
    ,Material.*
FROM
            Components  AS Component
INNER JOIN  Materials   AS Material ON Component.Child_Material = Material.Material
WHERE
    Component.Parent_Code = @FinishedGoodCode
ORDER BY
     Component.Percentage_of_Parent DESC
    ,Material.Material

如您所见,该orderby字段不包含在Material. 出于这个原因,我觉得我不能只返回一组Material对象并仍然保持排序 - 我已经在 SQL 中执行了排序并添加了_sortField(我认为该字段可能是个坏主意)。

我用于读取 SQL 的 C# 代码如下所示:

public async Task<SortedList<int, Materials>> GET_SortedMaterials(IProgress<Report> progress, string finishedGoodCode)
{
    try
    {
        var report = new Report { Message = "Retrieving Sorted Materials", NewLine = true, StatusCode = Enums.StatusCode.Working };
        progress.Report(report);
        using (var context = new DBContext())
        {
            var ingredientList = await context.Database.SqlQuery<(int _sortField,Materials mat)>("[app].[GET_Customers]").ToListAsync();
            var sorted = new SortedList<int, Raw_Materials>();
            foreach (var (_sortField, mat) in ingredientList.OrderBy(x=>x._sortField))
            {
                sorted.Add(_sortField, mat);
            }
            return sorted;
        }
    }
    catch (Exception ex)
    { [EXCLUDED CODE]
    }
 }

当代码执行时,我得到了正确的返回行数,但我没有得到一个排序列表,其中Key对应于_sortField值和对应ValueMaterial值。我已经尝试了基本相同代码的各种不同版本,但我无法让脚本返回包含排序信息的材料列表,相反,转换为 EF 类完全失败,我只能返回空值:

不满意的结果

当排序字段不在返回值中时,任何关于如何从 SQL 返回排序列表并在 C# 中维护排序的建议都将非常感激。

标签: c#sql-serverentity-framework-6sortedlist

解决方案


利用

var ingredientList = await context.Database.SqlQuery<Materials>("[app].[GET_Customers]").Select((mat, _sortField) => (_sortField, mat)).ToDictionary(x => x._sortField, x => x.mat);

或者如果你想要异步加载使用

var ingredientList = await context.Database.SqlQuery<Materials>("[app].[GET_Customers]").ToListAsync().Result.Select((mat, _sortField) => (_sortField, mat)).ToDictionary(x => x._sortField, x => x.mat);

完整代码

public async Task<SortedList<int, Materials>> GET_SortedMaterials(IProgress<Report> progress, string finishedGoodCode)
{
   try
   {
       var report = new Report { Message = "Retrieving Sorted Materials", NewLine = true, StatusCode = Enums.StatusCode.Working };
       progress.Report(report);
       using (var context = new DBContext())
       {
           var ingredientList = await context.Database.SqlQuery<Materials>("[app].[GET_Customers]").ToListAsync().Result.Select((mat, _sortField) => (_sortField, mat)).ToDictionary(x => x._sortField, x => x.mat);
           var sorted = new SortedList<int, Raw_Materials>();
           foreach (var item in ingredientList.OrderBy(x => x.Key))
           {
               sorted.Add(item.Key, item.Value);
           }
           return sorted;
       }
   }
   catch (Exception ex)
   {
      [EXCLUDED CODE]
   }
}

推荐阅读