使用AddOrUpdate()
时如何访问ASP.NET Core 2
方法?
AddOrUpdate()
命名空间中的EntityFramework 6
中有System.Data.Entity.Migrations
。但是当我想在ASP.NET Core 2
中使用这种方法时,我找不到它。
答案 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。
如有遗漏,请告诉我。谢谢。