我为这样的几种类型创建了自己的InsertOrUpdate()
实现:
public IEnumerable<Genre> InsertOrUpdate(IEnumerable<Genre> genres)
{
foreach (var genre in genres)
{
var existingGenre = _context.Genres.SingleOrDefault(x => x.TmdbId == genre.TmdbId);
if (existingGenre != null)
{
existingGenre.Update(genre);
yield return existingGenre;
}
else
{
_context.Genres.Add(genre);
yield return genre;
}
}
_context.SaveChanges();
}
返回类型IEnumerable<T>
是必需的,因为它将用于在datacontext中插入根对象。此方法基本上检索附加对象(如果存在)并使用最新值更新它(如果它没有)或将其作为新对象插入(如果它不存在)。然后返回此附加对象,以便它可以链接到多对多表中的根对象。
现在的问题是我有几个这样的集合(流派,海报,关键字等),每个类型的ID设置不同:有时它被称为TmdbId
,有时{ {1}},有时Id
。使用界面并将其全部重命名为Iso
是一回事,但问题在于它们也是不同的类型:一些是Id
,一些是int
。< / p>
问题很简单:我如何将其变成更通用的东西以避免代码重复?
到目前为止,我一直在玩
string
但显然这不起作用,因为我无法访问内部public IEnumerable<T> InsertOrUpdate<T>(IEnumerable<T> entities, Func<T, bool> idExpression) where T : class
{
foreach (var entity in entities)
{
var existingEntity = _context.Set<T>().SingleOrDefault(idExpression);
if (existingEntity != null)
{
_context.Entry(existingEntity).CurrentValues.SetValues(entity);
yield return existingEntity;
}
else
{
_context.Set<T>().Add(entity);
yield return entity;
}
}
_context.SaveChanges();
}
变量。旁注:entity
does not work in my scenario。
答案 0 :(得分:1)
你可以尝试:
public IEnumerable<T> InsertOrUpdate<T>(IEnumerable<T> entities, Func<T, object[]> idExpression) where T : class
和
var existingEntity = _context.Set<T>().Find(idExpression(entity));
用类似
的方式调用movie.Genres = new List<Genre>(InsertOrUpdate(movie.Genres, x => new object[] { x.Id }));
(请注意,返回IEnumerable<>
的方法非常危险...如果您不进行枚举,例如
InsertOrUpdate(movie.Genres, x => x.Id);
然后该方法将不会被完全执行,因为它将被“按需”延迟执行)
如果您只有单键表,可以将其更改为:
public IEnumerable<T> InsertOrUpdate<T>(IEnumerable<T> entities, Func<T, object> idExpression) where T : class
和
var existingEntity = _context.Set<T>().Find(new object[] { idExpression(entity) });
和
movie.Genres = new List<Genre>(InsertOrUpdate(movie.Genres, x => x.Id));