首页 > 解决方案 > 使用 Z.EntityFramework.Plus 更新不会更新数据

问题描述

我的 UnitOfWork 存储库中有一个更新方法,如下所示:

public async Task<int> UpdateAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> updateExpression)
{
     return await dbSet.Where(predicate).UpdateAsync(updateExpression);
}

我的逻辑中也有一个更新方法,如下所示:其中 BetSelection 有一个选择 ID 作为外键。

private async Task UpdateBetSelections(Table table)
{
     await _unitOfWork.BetSelection
          .UpdateAsync(bs => bs.Selection.TableId == table.Id && bs.Selection.RoundId == table.CurrentRound,
     bs => new BetSelection()
     {
           Status = bs.Selection.Status
     });
}

我正在尝试将一轮的所有 BetSelection 记录状态更新为其相应选择状态的状态。查询没有抛出任何错误,也没有更新记录。

标签: c#sqldatabaseasp.net-coreentity-framework-core

解决方案


更新

根据this,尚不支持复杂类型

Github问题

原始答案

不幸的是,看起来有一个错误。我创建了小型复制器,它生成了以下 sql。没有提到导航属性。

UPDATE A
SET A.[Status] = B.[Status]
FROM [BetSelections] AS A
INNER JOIN ( SELECT [b].[Id], [b].[SelectionId], [b].[Status]
FROM [BetSelections] AS [b]
           ) AS B ON A.[Id] = B.[Id]

重现代码

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Z.EntityFramework.Plus;

namespace ConsoleApp1
{
    public class Selection
    {
        public int Id { get; set; }

        public int Status { get; set; }

        public virtual ICollection<BetSelection> Selections { get; set; }
    }

    public class BetSelection
    {
        public int Id { get; set; }

        public int Status { get; set; }

        public int SelectionId { get; set; }

        public virtual Selection Selection { get; set; }
    }

    public class AppDbContext : DbContext
    {
        public DbSet<Selection> Selections { get; set; }

        public DbSet<BetSelection> BetSelections { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=DESKTOP-5PVJ0I5;Database=zefcore-so1;Integrated Security=true");

            base.OnConfiguring(optionsBuilder);
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            BatchUpdateManager.BatchUpdateBuilder = builder => {
                builder.Executing = c =>
                {
                    Console.WriteLine(c.CommandText);
                };
            };

            var db = new AppDbContext();

            var selection = db.Selections.Add(new Selection()
            {
                Status = 1,
            });

            db.BetSelections.Add(new BetSelection()
            {
                Selection = selection.Entity,
                Status = 2,
            });

            db.SaveChanges();

            await db.BetSelections
                .UpdateAsync(x => new BetSelection() { Status = x.Selection.Status });
        }
    }
}

此外,如果您将父字段重命名为其他名称,Status111在我的情况下,您将在下面的 sql 中获得无效列异常

UPDATE A
SET A.[Status] = B.[Status111]
FROM [BetSelections] AS A
INNER JOIN ( SELECT [b].[Id], [b].[SelectionId], [b].[Status]
FROM [BetSelections] AS [b]
           ) AS B ON A.[Id] = B.[Id]

推荐阅读