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

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

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

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

最佳答案

这可能是你想要的

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 .
如果有任何遗漏,请告诉我。谢谢你。

关于entity-framework - asp.net Core 2 中的 AddOrUpdate() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47971739/

相关文章:

c# - 使用 LINQ 和 Entity Framework (核心)从一个 SQL 查询中的多个表中提取数据

c# - Entity Framework 是否有某种上下文缓存?

c# - 不支持从 _ 到 _ 的关系,因为拥有的实体类型 _ 不能位于非所有权关系的主体端

.net - 如何使用 .NET 4.6.1 导出到 EF Core 1.1 中的脚本

c# - 在 Azure Functions 2.0 中使用 EasyAuth 时,依赖项将 ClaimsPrincipal 注入(inject) DbContext

asp.net - ASP .Net Core 2.2 发布到 Azure

c# - 不使用 ASP.Net Core 2 中的迁移命令 Update-Database 创建数据库

c# - 唯一列,检查现有记录,最佳方法

c# - .NET Core 2.0 中的 HttpWebRequest 抛出 302 发现异常

entity-framework - 可以广播消息时,消息系统如何组织数据库表?