C#从实体框架向列表中插入顺序

C#从实体框架向列表中插入顺序,c#,asp.net,asp.net-mvc,entity-framework,C#,Asp.net,Asp.net Mvc,Entity Framework,当我从实体框架Select实例化C#列表时,我惊讶地发现在C#列表中存在插入顺序问题 我正在创建多个dto,其中包含键的列表,但每个dto对象的插入顺序是随机的。这是最奇怪的事情。我认为C#list中的插入顺序是保留的,所以我试图找出顺序的确定位置 服务器代码: var locations = Context.Location .Where(x => x.fk_LocationId == id) .Include(t => t.DoctorLocati

当我从实体框架Select实例化C#列表时,我惊讶地发现在C#列表中存在插入顺序问题

我正在创建多个dto,其中包含键的
列表
,但每个dto对象的插入顺序是随机的。这是最奇怪的事情。我认为C#list中的插入顺序是保留的,所以我试图找出顺序的确定位置

服务器代码:

var locations = Context.Location
        .Where(x => x.fk_LocationId == id)
        .Include(t => t.DoctorLocations);

Region.Locations = locations
        .SelectMany(x => x.DoctorLocations)
        .Where(y => y.fk_LocationId == id)
        .Select(x =>
            new SortableItem
            {
                Keys = new List<int> { x.fk_doctorId, x.fk_locationId },
                Type = "Practice",
                Priority = x.Priority ?? 0,
            })
        .OrderBy(x => x.Priority)
        .ToList();

看起来EF6在处理包含新列表{val1,val2,…}等结构的投影时出现了错误。虽然它不生成
NotSupportedException
,但正确具体化结果所需的生成的SQL
ORDER BY
子句是错误的(使用常量而不是索引选择器表达式)

如果您不需要
IQueryable
result,我建议您使用通常的双重投影解决方法-在LINQ to Entities查询中使用普通匿名类型投影,然后在末尾切换到LINQ to Objects并执行所需的投影:

var result = locations
    .SelectMany(x => x.DoctorLocations)
    .Where(y => y.fk_LocationId == id)
    .Select(x => new
    {
        K1 = x.fk_doctorId, K2 = x.fk_locationId,
        Type = "Practice",
        Priority = x.Priority ?? 0,
    })
    .OrderBy(x => x.Priority)
    .AsEnumerable() // switch to L2O
    .Select(x => new SortableItem
    {
        Keys = new List<int> { x.K1, x.K2 },
        Type = x.Type,
        Priority = x.Priority,
    })
    .ToList();
var结果=位置
.SelectMany(x=>x.doctor位置)
.Where(y=>y.fk_LocationId==id)
.选择(x=>new
{
K1=x.fk_doctorId,K2=x.fk_locationId,
Type=“实践”,
优先级=x。优先级??0,
})
.OrderBy(x=>x.Priority)
.AsEnumerable()//切换到L2O
.选择(x=>new SortableItem
{
Keys=新列表{x.K1,x.K2},
类型=x.类型,
优先级=x.优先级,
})
.ToList();

我知道,这很烦人,但至少效果和预期的一样:)

它真的是随机的吗?看起来您的
SelectMany
可能会出错,因此它会按每个位置的优先级进行次分类,而不是按全局优先级进行排序。你得到的是1-2-3-1-2-3而不是1-1-2-2-3-3吗?很难说,Keys=newlist{x.fk_doctorId,x.fk_locationId}将在让医生成为第一个id和让位置成为第一个id之间交替。我认为你对selectmany的看法是正确的。我会看看是否可以删除它,并找到另一种测试方法。查询看起来还可以。生成的SQL是什么?这是一个很好的问题。让我检查一下。嗯,你是指
列表中元素的顺序吗?看起来EF处理这种类型的投影时有一个bug。我刚刚尝试了一些类似的方法,但SQL完全错误(最新的EF6.1.3)实现了这一点。谢谢你,谢谢你解释为什么它解决了这个问题。
Region.Locations = Context.DoctorLocations
        .Where(y => (y.fk_doctorId == doctorId) &&
            locations.Select(x => x.locationId).Contains(y.fk_locationId))
        .Where(y => y.fk_doctorId == doctorid)
        .Select(x =>
            new SortableItem {
                Keys = new List<int> { x.fk_doctorId, x.fk_locationId }
            })
        .OrderBy(x => x.Priority)
        .ToList();
var result = locations
    .SelectMany(x => x.DoctorLocations)
    .Where(y => y.fk_LocationId == id)
    .Select(x => new
    {
        K1 = x.fk_doctorId, K2 = x.fk_locationId,
        Type = "Practice",
        Priority = x.Priority ?? 0,
    })
    .OrderBy(x => x.Priority)
    .AsEnumerable() // switch to L2O
    .Select(x => new SortableItem
    {
        Keys = new List<int> { x.K1, x.K2 },
        Type = x.Type,
        Priority = x.Priority,
    })
    .ToList();