C# 如何从包含中选择最后一行

C# 如何从包含中选择最后一行,c#,asp.net,entity-framework,linq,entity-framework-core,C#,Asp.net,Entity Framework,Linq,Entity Framework Core,我正在使用EF7和MVC5创建一个web应用程序。我需要从数据库中选择所有标题行 这些行将使用如下所示的类: public class Log_Header { [Key] public int Id { get; set; } public string App_Name { get; set; } public string App_Url { get; set; } public string Submitted_By { get; set; }

我正在使用EF7和MVC5创建一个web应用程序。我需要从数据库中选择所有标题行

这些行将使用如下所示的类:

public class Log_Header
{
    [Key]
    public int Id { get; set; }
    public string App_Name { get; set; }
    public string App_Url { get; set; }
    public string Submitted_By { get; set; }
    public string App_Contact { get; set; }
    public string App_Description { get; set; }

    public ICollection<Log_Detail> Details { get; set; }
}
现在我遇到了一个问题,我只需要
Details
中的最后一行(max-id行),但我找不到一种方法。我尝试过几种方法,但都不走运,我想它看起来会像这样:

_context.LogHeader.Include(t => t.Details.Last()).ToList();
我经常遇到的错误是:

中发生“System.InvalidCastException”类型的异常 EntityFramework.Core.dll,但未在用户代码中处理

其他信息:无法强制转换类型为的对象 “Remotion.Linq.子句.Expressions.SubQueryExpression”以键入 'System.Linq.Expressions.MemberExpression'


如果任何人有任何线索,请留下评论或回答,请记住这是使用EF 7。

EF不支持只包含第一行/最后一行/任何行。 EF仅支持包含整个表(即,它进行连接)。 因此,您将始终获得
Log\u Header.Count()*Log\u Detail().Count()
行。 这将花费您大量的性能

最好通过两次往返将数据加载到数据库。 更好的是:以并行和异步方式进行

public async Task<IEnumerable<Log_Header>> GetHeaderWithLastDetailAsync()
{
    var headerTask = GetLogHeadersAsync();
    var detailTask = GetLastDetailByHeaderIdAsync();

    await Task.WhenAll(headerTask, detailTask).ConfigureAwait(false);

    var header = headerTask.Result;
    var detail = detailTask.Result;

    foreach(var h in header)
    {
        Log_Detail d;
        if(detail.TryGetValue(h.Id, out d)
            h.Details.Add(d);
    }
}

public async Task<IEnumerable<Log_Header>> GetLogHeadersAsync()
{
    using(var context = new MyContext())
    {
        context.Configuration.AutoDetectChangesEnabled = false;
        context.Configuration.ProxyCreationEnabled = false;
        return await context.LogHeader.ToListAsync().ConfigureAwait(false);
    }
}

public async Task<IDictionary<int, Log_Detail>> GetLastDetailByHeaderIdAsync()
{
    using(var context = new MyContext())
    {
        context.Configuration.AutoDetectChangesEnabled = false;
        context.Configuration.ProxyCreationEnabled = false;
        return await context.LogDetail.ToDictionaryAsync(d => d.HeaderId).ConfigureAwait(false);
    }
}
公共异步任务GetHeaderWithLastDetailAsync() { var headerTask=getLogHeaderAsync(); var detailTask=GetLastDetailByHeaderIdAsync(); wait Task.WhenAll(headerTask,detailTask).configurewait(false); var header=headerTask.Result; var detail=detailTask.Result; foreach(表头中的var h) { 日志详细信息d; if(详细信息TryGetValue(h.Id,out d) h、 详情.添加(d); } } 公共异步任务getLogHeaderAsync() { 使用(var context=new MyContext()) { context.Configuration.AutoDetectChangesEnabled=false; context.Configuration.ProxyCreationEnabled=false; 返回wait context.LogHeader.ToListAsync().configurewait(false); } } 公共异步任务GetLastDetailByHeaderIdAsync() { 使用(var context=new MyContext()) { context.Configuration.AutoDetectChangesEnabled=false; context.Configuration.ProxyCreationEnabled=false; 返回wait context.LogDetail.ToDictionaryAsync(d=>d.HeaderId).configurewait(false); } }
Include需要导航属性的路径,而不是实际的成员。我相信您最好的选择是延迟加载所需的对象,而不是急切地加载树。@DevilSuichiro感谢您的回复。我相信EF 7目前不支持延迟加载…所以这有点问题。您是否尝试过\u context.LogHeader.Includee(t=>t.Details.LastOrDefault()).ToList();@janina是的,我得到了相同的错误。而且
Details
将始终有一个值。您看到示例了吗?也许您可以使用left join@furchick
public async Task<IEnumerable<Log_Header>> GetHeaderWithLastDetailAsync()
{
    var headerTask = GetLogHeadersAsync();
    var detailTask = GetLastDetailByHeaderIdAsync();

    await Task.WhenAll(headerTask, detailTask).ConfigureAwait(false);

    var header = headerTask.Result;
    var detail = detailTask.Result;

    foreach(var h in header)
    {
        Log_Detail d;
        if(detail.TryGetValue(h.Id, out d)
            h.Details.Add(d);
    }
}

public async Task<IEnumerable<Log_Header>> GetLogHeadersAsync()
{
    using(var context = new MyContext())
    {
        context.Configuration.AutoDetectChangesEnabled = false;
        context.Configuration.ProxyCreationEnabled = false;
        return await context.LogHeader.ToListAsync().ConfigureAwait(false);
    }
}

public async Task<IDictionary<int, Log_Detail>> GetLastDetailByHeaderIdAsync()
{
    using(var context = new MyContext())
    {
        context.Configuration.AutoDetectChangesEnabled = false;
        context.Configuration.ProxyCreationEnabled = false;
        return await context.LogDetail.ToDictionaryAsync(d => d.HeaderId).ConfigureAwait(false);
    }
}