回到目錄
在對MongoDB進行封裝後,對于Update更新對象裡的集合屬性時出現了一個現象,讓人感到很惡心,人家更新前是個美麗的Array,但是更新之後集合對象變成了鍵值對,鍵是集合的類型名稱,值是真實的數組值,哈哈,這個問題起初困擾了我很久,今天終于豁然開朗了,原來是Update方法的問題,呵呵!
看原來的值
看更新後的變質的值
再看看我們的Update方法
public Task UpdateAsync(TEntity item)
{
var query = new QueryDocument("_id", typeof(TEntity).GetProperty(EntityKey).GetValue(item).ToString());
var fieldList = new List<UpdateDefinition<TEntity>>();
foreach (var property in typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (property.Name != EntityKey)//更新集中不能有實體鍵_id
{
fieldList.Add(Builders<TEntity>.Update.Set(property.Name, property.GetValue(item)));
}
}
return ForWait(() => _table.UpdateOneAsync(query, Builders<TEntity>.Update.Combine(fieldList)));
}
确實沒看出什麼問題來,但最後它生成的代碼是以_t和_v為鍵值的值,出現這種情況的原因是你的代碼沒有被mongo識别,就像之前我們為mongo傳decimal類型的資料一樣,它也會出現同樣的情況。
解決方法
将複雜類型進行拆封群組裝,讓它被mongo所認識,這樣update操作就可以按着我們預想的完成了,值得注意的是,如果你的對象裡有複雜類型,如Person類裡有Address類型,那麼在指派時我們拼成以下這樣
Address.City="北京"
而如果你的對象裡屬性為集合類型,那就更麻煩一些,除了做上面的拆封外,還要關注它的索引号,如Person類裡有AddList集合屬性,那麼在指派時我們拼成以下這樣
AddList.0.City="北京"
下面公開大叔的Update代碼
public Task UpdateAsync(TEntity item)
{
var query = new QueryDocument("_id", typeof(TEntity).GetProperty(EntityKey).GetValue(item).ToString());
var fieldList = new List<UpdateDefinition<TEntity>>();
foreach (var property in typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
//非空的複雜類型
if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && property.GetValue(item) != null)
{
if (typeof(IList).IsAssignableFrom(property.PropertyType))
{
#region 集合類型
foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (sub.PropertyType.IsClass && sub.PropertyType != typeof(string))
{
var arr = property.GetValue(item) as IList;
if (arr != null && arr.Count > 0)
{
for (int s = 0; s < arr.Count; s++)
{
foreach (var subInner in sub.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
//propertyName.index.innerPropertyName
fieldList.Add(Builders<TEntity>.Update.Set(property.Name + "."+ s + "." + subInner.Name, subInner.GetValue(arr[s])));
}
}
}
}
}
#endregion
}
else
{
#region 實體類型
//複雜類型,導航屬性,類對象和集合對象
foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
fieldList.Add(Builders<TEntity>.Update.Set(property.Name + "." + sub.Name, sub.GetValue(property.GetValue(item))));
}
#endregion
}
}
else //簡單類型
{
if (property.Name != EntityKey)//更新集中不能有實體鍵_id
{
fieldList.Add(Builders<TEntity>.Update.Set(property.Name, property.GetValue(item)));
}
}
}
return ForWait(() => _table.UpdateOneAsync(query, Builders<TEntity>.Update.Combine(fieldList)));
}
希望本文章對使用MongoDB的學生來說有所幫助!
作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!
