假設我們有以下代碼:
Category[] categoriesOne = new Category[] {
// each instance contains a lot of properties but without Desc property being set
// the content of Desc property is only available in categoriesTwo
new Category { IdCategory = 1, Name = "Pasta", ...},
new Category { IdCategory = 2, Name = "Beverages", ...},
new Category { IdCategory = 3, Name = "Other food", ...},
};
Category[] categoriesTwo = new Category[] { // only two properties in each instance
new Category { IdCategory = 1, Desc = "made in Italy"},
new Category { IdCategory = 2, Desc = "made in Germany"},
};
public class Category
{
public int IdCategory { get; set; }
public String Name { get; set; }
public String Desc{ get; set; }
// ... many more properties such as barcode, supplier, country, countrycode ... etc
}
我想做一個內部連接并填充 Desc 屬性,所以作為 IEnumerable 的回傳實體應該是:
{
new Category { IdCategory = 1, Name = "Pasta", Desc = "made in Italy"},
new Category { IdCategory = 2, Name = "Beverages", Desc = "made in Germany"}
}
它看起來是一個非常簡單的任務,我們通常可以做到:
var query = categoriesOne.Join(categoriesTwo, c1 => c1.IdCategory, c2 => c2.IdCategory, (c1, c2) => new { c1, c2 });
foreach (var item in query)
{
item.c1.Desc = item.c2.Desc;
}
但它看起來不是一個好的/有效的方法,我們有沒有更優雅的方法,所以我們可以一次性完成:
var query = from c1 in categoriesOne
join c2 in categoriesTwo on c1.IdCategory equals c2.IdCategory into groups
???
請注意,我不能這樣做:
var result = (from c1 in categoriesOne
join c2 in categoriesTwo on c1.IdCategory equals c2.IdCategory
select new Category
{
IdCategory = c1.IdCategory,
Name = c1.Name,
Desc = c2.Desc
// ... too many properties from categoriesOne, this approach is tedious
}
).ToList();
因為 Category 類包含很多屬性,所以基本上我想保留所有屬性categoriesOne(除了 Desc 屬性,其內容僅在categoriesTwo
uj5u.com熱心網友回復:
我想到的關于合并兩個物件的問題是,誰是源,誰是目標,或者都是物體源,應該創建一個新目標?您必須在該select條款內做出此決定。為了避免繁瑣的代碼行,您可以使用一些反射材料并從一個或多個源讀取所有屬性,獲取第一個非默認值并將其寫入所需的目標。
public static class Helper
{
public static T Merge<T>(T target, params T[] sources) where T : class, new()
{
if (target == null)
target = new T();
var props = typeof(T).GetProperties()
.Where(prop => prop.CanRead && prop.CanWrite);
foreach (var prop in props)
{
var value = sources.Select(source => prop.GetValue(source))
.FirstOrDefault(value => value != default);
prop.SetValue(target, value);
}
return target;
}
}
使用這個助手,您應該能夠撰寫如下內容:
var result = (from c1 in categoriesOne
join c2 in categoriesTwo on c1.IdCategory equals c2.IdCategory
select Helper.Merge(null, c1, c2)
).ToList();
或者
var result = (from c1 in categoriesOne
join c2 in categoriesTwo on c1.IdCategory equals c2.IdCategory
select Helper.Merge(c1, c2)
).ToList();
取決于您是想從這兩個實體中創建一個新實體還是操縱第一個實體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/494224.html
上一篇:EntityFrameworkCoreLINQ運算式無法轉換為SQL
下一篇:.NetWebAPI-管理器與存盤庫Find(Expression<Func<TEntity,bool>>運算式)方法的互動
