c# - 如何从“包含”中选择最后一行

标签 c# asp.net entity-framework linq entity-framework-core

我正在使用 EF 7 和 MVC 5 创建 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; }
}

如您所见,我有一个 Log_Details 集合。

我使用的语句如下:

public IEnumerable<Log_Header> getLogHeaders()
{
     return _context.LogHeader.Include(t => t.Details).ToList();
}

现在出现了我遇到的问题,我只需要 Details 中的最后一行(最大 id 行),但我找不到方法来做到这一点。我尝试了几种方法,但没有成功,认为它看起来与此类似:

_context.LogHeader.Include(t => t.Details.Last()).ToList();

我不断收到的错误是:

An exception of type 'System.InvalidCastException' occurred in EntityFramework.Core.dll but was not handled in user code

Additional information: Unable to cast object of type 'Remotion.Linq.Clauses.Expressions.SubQueryExpression' to type 'System.Linq.Expressions.MemberExpression'.

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

最佳答案

EF 不支持仅包含第一行/最后一行/任意行。 EF 仅支持包含整个表(即它执行 JOIN)。 因此,您将始终获得 Log_Header.Count() * Log_Detail().Count() 行。 这会消耗大量的性能。

更好地将数据加载到数据库的 2 次往返中。 更好的是:并行和异步地执行它们。

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);
    }
}

关于c# - 如何从“包含”中选择最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35408488/

相关文章:

c# - C#和golang的MD5不一致

c# - 可以通过 C# 将类添加到对象的现有类属性吗?

c# - 当我尝试 getallUsers() 时,序列不包含匹配元素错误

sql-server - 如何从 Entity Framework 访问FileTables?

c# - Window 服务中的线程池?

c# - C#多线程-锁定

c# - Pinvoke C# : delegated function cause crash

c# - Asp.net Web API 无法从文件路径读取文件

javascript - 如何通过 ID 仅隐藏列表项中的图像?

entity-framework - Entity Framework 6 代码优先 - 存储库实现是一个好的实现吗?