【问题标题】:Collections of child objects are loaded, single child objects are overwritten (is this a lazy-loading issue?)加载子对象的集合,覆盖单个子对象(这是延迟加载问题吗?)
【发布时间】:2021-07-16 15:12:41
【问题描述】:

我正在使用 EF Core 5.08(Blazor 服务器应用程序)。

我有一个类 Assignment 具有以下属性:

public Guid AssignmentId { get; set;    
public Guid AssetId { get; set; }
public virtual Asset Asset { get; set; }
public virtual List<Person> People { get; set }

public Assignment(){ 
     this.AssignmentId = Guid.NewGuid();
     this.Asset = new Asset();
     this.People = new List<Person>();
}

班级Asset

public Guid AssetId { get; set; }    
public virtual List<Assignment> Assignments

public Asset() {
     this.AssetId = Guid.NewGuid();
     this.Assignments = new List<Assignment>();
}

AssignmentPerson 具有多对多关系。 AssetAssignment 具有一对多的关系(即每个分配引用一个 Asset,而每个 Asset 引用一组 Assignments)。

实体框架创建连接表AssignmentPerson;再加上启用的延迟加载,我可以访问和呈现剃须刀组件中Assignment.People 的属性。

在 razor 组件中,当我访问 Assignment.AssetId 时,外键是预期的(即它是数据库中相应 Asset 的主键)。

奇怪的是,当我访问和渲染Assignment.Asset.AssetId 时,Asset 主键不是外键(Assignment.AssetId);似乎在我预期的 Asset 的位置上构建了一个新的 Asset

我认为这与延迟加载有关。外键怎么可能是正确的但Assignment.Asset会被覆盖?

为了在 razor 组件中获取分配,我注入我的服务 AssignmentService 并调用它的方法:

    public List<Assignment> Get(Guid workspaceId)
    {
        Workspace workspace = context.Workspaces.Find(workspaceId);
        return workspace.Assignments;
    }

    public Task<List<Assignment>> GetAsync(Guid workspaceId)
    {
        return Task.Run(() => this.Get(workspaceId));
    }

     protected override async Task OnInitializedAsync()
     {
          this.assignments = await assignmentService.GetAsync(Guid.Parse("//The Workspace.Guid"));
     }

【问题讨论】:

  • @HenkHolterman 感谢阅读 - 添加了我查询上下文的方法。
  • 好的。旁注:用异步方法替换 Task.Run 。但这不是原因。
  • 现在我们需要看看Assigment & Asset的建模。 OnModelCreating() 或属性。
  • 另外提一下EF版本,这个可能最近变了。
  • 我仍然看不到任何模型绑定。你有 OnModelCreating 吗?

标签: c# entity-framework blazor lazy-loading


【解决方案1】:

不应该有任何延迟加载。我不确定 Find() 做了什么,但试试这个:

public List<Assignment> Get(Guid workspaceId)
{
    Workspace workspace = context
      .Workspaces
      .Include(ws => ws.Assignments).ThenInclude(a => a.Asset)
      .SingleOrDefault(ws => ws.WorkspaceId == workspaceId);
    return workspace.Assignments;
}

此外,应由 Db 生成 Id,EF 将 default(Guid) 识别为 NULL。所以,

  //this.AssetId = Guid.NewGuid();  -- don't do this

并且 Assignment 构造函数应该初始化 Asset 属性。

初始化List&lt;&gt; 属性是可以的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-13
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多