asp.net Core 2中的AddOrUpdate()方法

时间:2017-12-25 20:15:36

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

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

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

1 个答案:

答案 0 :(得分:0)

这可能就是您想要的

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);
    }
}

为简洁起见,我省略了评论。

像这样使用

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

如有遗漏,请告诉我。谢谢。