【问题标题】:AddOrUpdate() method in asp.net Core 2asp.net Core 2 中的 AddOrUpdate() 方法
【发布时间】:2020-09-28 18:26:43
【问题描述】:

使用ASP.NET Core 2时如何访问AddOrUpdate()方法?

EntityFramework 6 中有AddOrUpdate()System.Data.Entity.Migrations 命名空间。但是当我想在ASP.NET Core 2中使用这个方法时,却找不到了。

【问题讨论】:

标签: entity-framework entity-framework-core asp.net-core-2.0


【解决方案1】:

这可能是你想要的

public static class DbSetExtension
{
    /// <exception cref="ArgumentNullException"></exception>
    public static TEntity FindEntity<TEntity>(this DbSet<TEntity> dbSet, TEntity entity, bool noTracking = false) where TEntity : class
    {
        if (entity == null)
        {
            throw new ArgumentNullException(nameof(entity));
        }

        var dbContext = dbSet.GetService<ICurrentDbContext>().Context;
        var entityEntry = dbContext.Entry(entity);
        var entityType = entityEntry.Metadata;
        var primaryKey = entityType.FindPrimaryKey();
        if (primaryKey == null)
        {
            return (noTracking ? dbSet.AsNoTracking() : dbSet).FirstOrDefault(item => item.Equals(entity));
        }

        var ids = primaryKey.Properties.Select(item => item.PropertyInfo.GetValue(entity)).ToArray();
        var result = dbSet.Find(ids);
        if (noTracking && result != null)
        {
            dbContext.Entry(result).State = EntityState.Detached;
        }

        return result;
    }

    /// <exception cref="ArgumentNullException"></exception>
    public static async ValueTask<TEntity> FindEntityAsync<TEntity>(this DbSet<TEntity> dbSet, TEntity entity, bool noTracking = false)
        where TEntity : class
    {
        if (entity == null)
        {
            throw new ArgumentNullException(nameof(entity));
        }

        var dbContext = dbSet.GetService<ICurrentDbContext>().Context;
        var entityEntry = dbContext.Entry(entity);
        var entityType = entityEntry.Metadata;
        var primaryKey = entityType.FindPrimaryKey();
        if (primaryKey == null)
        {
            return await (noTracking ? dbSet.AsNoTracking() : dbSet).FirstOrDefaultAsync(item => item.Equals(entity));
        }

        var ids = primaryKey.Properties.Select(item => item.PropertyInfo.GetValue(entity)).ToArray();
        var result = await dbSet.FindAsync(ids);
        if (noTracking && result != null)
        {
            dbContext.Entry(result).State = EntityState.Detached;
        }

        return result;
    }

    /// <exception cref="ArgumentNullException"></exception>
    public static EntityEntry<TEntity> Update<TEntity>(this DbSet<TEntity> dbSet, TEntity entity, bool? includeOrExclude = null,
        params string[] propertyNames) where TEntity : class
    {
        if (entity == null)
        {
            throw new ArgumentNullException(nameof(entity));
        }

        var entityEntry = dbSet.Update(entity);
        if (includeOrExclude != null)
        {
            foreach (var property in entityEntry.Properties)
            {
                if (includeOrExclude.Value ^ propertyNames?.Contains(property.Metadata.PropertyInfo.Name) == true)
                {
                    property.IsModified = false;
                }
            }
        }

        return entityEntry;
    }

    /// <exception cref="ArgumentNullException"></exception>
    public static EntityEntry<TEntity> AddOrUpdate<TEntity>(this DbSet<TEntity> dbSet, TEntity entity, bool? includeOrExclude = null,
        params string[] propertyNames) where TEntity : class
    {
        if (dbSet.FindEntity(entity, true) == null)
        {
            return dbSet.Add(entity);
        }

        return dbSet.Update(entity, includeOrExclude, propertyNames);
    }

    /// <exception cref="ArgumentNullException"></exception>
    public static async ValueTask<EntityEntry<TEntity>> AddOrUpdateAsync<TEntity>(this DbSet<TEntity> dbSet, TEntity entity, bool? includeOrExclude = null,
        params string[] propertyNames) where TEntity : class
    {
        if (await dbSet.FindEntityAsync(entity, true) == null)
        {
            return await dbSet.AddAsync(entity);
        }

        return dbSet.Update(entity, includeOrExclude, propertyNames);
    }
}

为简洁起见,我省略了 cmets。

这样使用

var people = new People {
Id=1,
Name="Tom",
ChangeTime=DateTimeOffset.Now
AddTime=DateTimeOffset.Now,
};

await dbContext.AddOrUpdateAsync(people, false, nameof(people.AddTime));
await dbContext.SaveChangesAsync();

await dbContext.AddOrUpdateAsync(people, true, nameof(people.Name), nameof(people.ChangeTime));
await dbContext.SaveChangesAsync();

你也可以使用它的同步方式。

我在“Microsoft.EntityFrameworkCore 2.1.1”和“Microsoft.EntityFrameworkCore 3.1.7”测试正常。

您可能需要更多:Saving an explicit value during add

如果实体使用自动生成的键值。另见:Saving single entities

如有遗漏,请告知。谢谢。

【讨论】:

    猜你喜欢
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    相关资源
    最近更新 更多