[英]Generic Data Access layer to update navigational properties
我有以下通用數據訪問類,負責數據庫操作。
internal sealed class DataStore<T> : IDataStore<T>
where T : BaseModel, new()
{
private readonly DataContext _context;
public DataStore(DataContext context)
{
this._context = context;
}
public async Task InsertNew(T obj)
{
await Task.Run(async () =>
{
_context.Set<T>().Add(obj);
await _context.SaveChangesAsync();
});
}
public async Task<T> SelectObj(int id, Expression<Func<T, object>> includeExpression = null)
{
if (includeExpression != null)
return
await _context.Set<T>()
.Include<T, object>(includeExpression)
.FirstOrDefaultAsync(x => x.ID.Equals(id));
return await _context.Set<T>().Where(x => x.ID.Equals(id)).FirstOrDefaultAsync();
}
public async Task<List<T>> SelectAll(Expression<Func<T, object>> includeExpression = null)
{
if (includeExpression != null)
return await _context.Set<T>().Include<T, object>(includeExpression).ToListAsync();
return await _context.Set<T>().ToListAsync();
}
public async Task Update(T obj)
{
await Task.Run(async () =>
{
var original = await SelectObj(obj.ID);
_context.Entry(original).CurrentValues.SetValues(obj);
await _context.SaveChangesAsync();
});
}
public async Task Delete(T obj)
{
await Task.Run(async () =>
{
_context.Set<T>().Remove(obj);
await _context.SaveChangesAsync();
});
}
public async Task Delete(int id, Expression<Func<T, object>> includeExpression = null)
{
await Task.Run(async () =>
{
var obj = await SelectObj(id, includeExpression);
await Delete(obj);
});
}
}
Update
函數的問題是,它只更新傳遞的T
對象,而不是該對象的導航屬性。
我嘗試過以下方法,但是我被困住了,不確定我需要繼續這里。
private void GetNavProperties(T obj)
{
var objType = obj.GetType();
foreach (var prop in objType.GetProperties())
{
if (prop.PropertyType.IsClass)
{
var values = prop.GetValue(obj);
//How do I go further here, setting the Entity on the context
}
}
}
在玩完之后,我最終得到了適用於我的應用程序的以下解決方案。
以下是解決方案,其中包含用於解釋其功能的注釋。
private async Task UpdateNavProperties(T original, T newObject)
{
await Task.Run(async () =>
{
//get type of object
var objType = original.GetType();
//loop through properties on the Type
foreach (var prop in objType.GetProperties())
{
//Check that property is a class/reference type, and not part of the System namespace
//string would be part of the system namespace, but my custom class not
if (prop.PropertyType.IsClass && !prop.PropertyType.Namespace.Equals("System"))
{
//get the old value
var oldValue = prop.GetValue(original);
//get new value
var newValue = newObject.GetType().GetProperty(prop.Name).GetValue(newObject);
//update the value
_context.Entry(oldValue).CurrentValues.SetValues(newValue);
//save changes
await _context.SaveChangesAsync();
}
}
});
}
為了使用它,我做了以下事情:
public async Task Update(T obj, Expression<Func<T, object>> includeExpression = null)
{
await Task.Run(async () =>
{
var original = await SelectObj(obj.ID, includeExpression);
_context.Entry(original).CurrentValues.SetValues(obj);
await _context.SaveChangesAsync();
await UpdateNavProperties(original, obj);
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.