执行Update更新对象列表efcore .net核心

huangapple go评论59阅读模式
英文:

ExecuteUpdate update lists of objects efcore .net core

问题

我想知道新的ExecuteUpdate是否可以更新导航属性,这个属性是一个列表?

await _unitOfWork.Repositories<Domain.Team>().ExecuteUpdate(
x => x.Id == request.UpdateTeamMembersDto.Id,
x => x.SetProperty(x => x.TeamMembers, teamMembers)
);


这里团队和员工实体之间存在多对多关系,TeamMembers是中间表,所以我想使用ExecuteUpdate来更新TeamMembers列表,因为我不想在更新之前检索所有相关数据。

在这个上下文中,更新的含义是通过添加或删除新记录到TeamMembers属性来添加/删除TeamMembers到团队。

另一个问题是,ExecuteUpdate不等待SaveContext来保存更改,我可以改变这个行为,以便如果事务中出现问题,表不会受到影响吗?

这个方法相对较新,所以我没有找到类似这种的复杂用例。
英文:

I wonder if the new ExecuteUpdate can update navigation property which is a list?

await _unitOfWork.Repositories&lt;Domain.Team&gt;().ExecuteUpdate(
                x =&gt; x.Id == request.UpdateTeamMembersDto.Id,
                x =&gt; x.SetProperty(x =&gt; x.TeamMembers, teamMembers)
);

Here there is a many to many relationship between team and employee entities, TeamMembers is the intermidate table, so i want to update the list of TeamMembers using ExecuteUpdate because I didn't want to retrieve all the related data before updating them.

Update in this context mean Add/Remove TeamMembers from the Team by removing or adding new record to the TeamMembers property.

Another question ExecuteUpdate does not wait for SaveContext to save the changes, can i change this behavior so that if something goes wrong in the transaction the tables don't get effected?

This method is relatively new so i didn't found a complex use case for it like this.

答案1

得分: 1

没有,你不能使用ExecuteUpdate来更新导航属性(关系)。

public class UnitTest1
{
    private readonly BloggingContext db;
    private readonly Blog blog;
    private readonly List&lt;Post&gt; posts;
    public UnitTest1()
    {
        db = new BloggingContext();
        db.Database.EnsureCreated();
        blog = new Blog() {Url=&quot;1&quot;};
        posts = new (){ new Post(){Title=&quot;c&quot;}, new Post(){Title=&quot;d&quot;}};
        db.Blogs.Add(blog);
        var n = db.SaveChanges();
        Assert.Equal(1, n);
    }

    [Fact]
    public void Test1() // &lt;-- as usual
    {
        blog.Posts.AddRange(posts);
        var n = db.SaveChanges();
        Assert.Equal(2, n);
    }

    [Fact]
    public void Test2() // &lt;-- bulk
    {        
        var n = db.Blogs
            .Where(b =&gt; b.BlogId == blog.BlogId)
            .ExecuteUpdate(
                b =&gt; b.SetProperty(b =&gt; b.Posts, b =&gt; posts));
        Assert.Equal(2, n);
    }
}

失败! - 失败:1,通过:1,跳过:0,总共:2,持续时间:21毫秒

  • 测试1通过。
  • 测试2出错:
  错误消息:
   System.InvalidOperationException:无法翻译LINQ表达式'DbSet&lt;Blog&gt;()
    .Where(b =&gt; b.BlogId == __blog_BlogId_0)
    .ExecuteUpdate(b =&gt; b.SetProperty&lt;List&lt;Post&gt;&gt;(
        propertyExpression: b =&gt; b.Posts, 
        valueExpression: b =&gt; __posts_1))'。附加信息:以下'SetProperty'无法翻译:'SetProperty(b =&gt; b.Posts, b =&gt; __posts_1)'。在实体类型'Blog'上翻译成员'Posts'失败。这通常发生在指定的成员未映射时。有关更多信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038。

完整的测试代码在gist上

英文:

Is just a test to check it, spoiler:

No, you can not update navigation properties (Relationships) using ExecuteUpdate.

public class UnitTest1
{
    private readonly BloggingContext db;
    private readonly Blog blog;
    private readonly List&lt;Post&gt; posts;
    public UnitTest1()
    {
        db = new BloggingContext();
        db.Database.EnsureCreated();
        blog = new Blog() {Url=&quot;1&quot;};
        posts = new (){ new Post(){Title=&quot;c&quot;}, new Post(){Title=&quot;d&quot;}};
        db.Blogs.Add(blog);
        var n = db.SaveChanges();
        Assert.Equal(1, n);
    }

    [Fact]
    public void Test1() // &lt;-- as usual
    {
        blog.Posts.AddRange(posts);
        var n = db.SaveChanges();
        Assert.Equal(2, n);
    }

    [Fact]
    public void Test2() // &lt;-- bulk
    {        
        var n = db.Blogs
            .Where(b =&gt; b.BlogId == blog.BlogId)
            .ExecuteUpdate(
                b =&gt; b.SetProperty(b =&gt; b.Posts, b =&gt; posts));
        Assert.Equal(2, n);
    }
}

>Failed! - Failed: 1, Passed: 1, Skipped: 0, Total: 2, Duration: 21 ms

  • Test 1 passed.
  • Test 2 error:
  Error Message:
   System.InvalidOperationException : The LINQ expression &#39;DbSet&lt;Blog&gt;()
    .Where(b =&gt; b.BlogId == __blog_BlogId_0)
    .ExecuteUpdate(b =&gt; b.SetProperty&lt;List&lt;Post&gt;&gt;(
        propertyExpression: b =&gt; b.Posts, 
        valueExpression: b =&gt; __posts_1))&#39; could not be translated. Additional information: The following &#39;SetProperty&#39; failed to translate: &#39;SetProperty(b =&gt; b.Posts, b =&gt; __posts_1)&#39;. Translation of member &#39;Posts&#39; on entity type &#39;Blog&#39; failed. This commonly occurs when the specified member is unmapped. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

Full test code at gist

huangapple
  • 本文由 发表于 2023年2月7日 04:59:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75366528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定