【问题标题】:What's the correct way to reference tables using Code First with EF.Core for searching efficiently使用 Code First 和 EF.Core 引用表以进行有效搜索的正确方法是什么
【发布时间】:2020-07-06 21:57:09
【问题描述】:

对 EF.Core 来说还是个新手,我遇到了一些问题,因为我的表开始变得越来越复杂。这是我为我的类定义的示例。 注意...列和表比我在下面定义的要多得多。为了简洁起见,我已将它们配对。

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool Active { get; set; }
}

紧随其后

public class JournalEntry
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public string Details { get; set; }
    public DateTime DateEntered { get; set; }
    public virtual User User { get; set; }
}

我希望能够发出以下查询并包含用户表,这样我就可以使用用户表中的列填充 ViewModel,而无需进行其他查找并对检索数据时:

public IQueryable<JournalEntry> GetByUser(int userId)
{
    return _DbContext.JournalEntries.Where(j => j.UserId == userId)
                                            .Include(u => u.User)
                                            .OrderBy(u=> u.User.FirstName)
                                                .ThenBy(j => j.DateEntered);
}

然后,我的控制器将具有类似于以下内容的内容:

public IActionResult List(int userId)
{
    var journalEntries = new _dbRepository.GetByUser(userId);
    var myViewModel = new MyViewModel();
    myViewModel.UserName = ($"{journalEntries.User.FirstName} {journalEntries.User.LastName}");
    myViewModel.Entries = journalEntries; 
    etc ....
    return View(myViewModel);
}

我在视图模型中加载用户的名字和姓氏,以及引用的各种表中的任何其他属性。我遇到的问题是我在创建迁移时遇到错误“外键约束可能导致循环或多个级联路径。”当然,如果我删除了 公共虚拟用户用户{获取;放; } 来自 JournalEntry 类,然后问题就消失了(正如人们所期望的那样)。

我认为我做模型的方式是不正确的。我应该对这些模型进行编码的推荐方式是什么?我听说过“延迟加载”。那是我应该朝着的方向吗?

非常感谢。

--- 值

【问题讨论】:

  • 我认为您不需要Include 来进行排序。 Include 仅用于急切加载。
  • 不确定,但您需要将public List&lt;JournalEntry&gt; JournalEntries { get; set; } 添加到User 吗?如果这可行,但您不想要它,请尝试使用 Fluent API 来配置关系。

标签: c# asp.net-core ef-core-3.1


【解决方案1】:

您的查询返回 IQueryable&lt;JournalEntry&gt; 而不是 JournalEntry。 更改代码以从第一个对象中获取用户详细信息:

var myViewModel.UserName = ($"{journalEntries.First().User.FirstName} {journalEntries.First().User.LastName}");

在上面的行中,我在您的日记条目集合上调用First(),这将有一个User。然后我可以访问FirstNameLastName

另外,不要打扰LazyLoading,因为您正在学习。如果使用不当可能会导致select n+1 问题

【讨论】:

  • 学到了很多@dexter。看了你的回复,很有道理。我的效率不是很高。
猜你喜欢
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多