我经常要将一个集合投射到另一个集合中。使用从linq到对象的Select运算符非常容易:
var targetCollection = sourceCollection.Select(source => new Target
{
Source = source,
//some other stuff here
}
但我必须让收藏最终保持同步。在sourceCollection中添加或删除新项目时,更改必须反映在targetCollection中。我必须做这样的事情:
void OnSourceCollectionChanged(){
SyncCollections(sourceCollection, targetCollection)
}
void SyncCollections(ICollection<Source> sourceCollection, ICollection<Target> targetCollection)
{
//find items that are no longer present
var newItems = sourceCollection.Where(s => !targetCollection.Any(t => t.Source == s));
//find items that were added
var oldItems = targetCollection.Where(t => !sourceCollection.Any(s => t.Source == s));
foreach(var oldItem in oldItems) targetCollection.Remove(oldItem);
foreach(var source in newItems){
var target = new Target{ Source = source };
targetCollection.Add(target);
}
}
我相信已经有很好的图书馆来处理这种情况。你能推荐我一些吗?
我想到API,我只是指定投影,也许是“等式比较器”来比较源项目和目标项目:
var synchronizer = new CollectionSynchronizer<Source, Target>(
source => new Target
{
Source = source
});
synchronizer.Sync(sourceCollection, targetCollection);
//or specify filter as well:
synchronizer.Sync(
sourceCollection.Where(s => s.Created > DatTime.Now.AddMinutes(-5)),
targetCollection);
答案 0 :(得分:0)
您可以使用ObservableCollection
:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class Program
{
public static void Main()
{
var observableList = new ObservableCollection<string>();
var syncList = new List<string>(observableList);
observableList.CollectionChanged += (o,e) => {
foreach (var item in e.NewItems){
syncList.Add((string)item);
}
};
observableList.Add("Test");
Console.WriteLine(syncList[0]);
}
}
答案 1 :(得分:0)
如果您的源集合实现了INotifyCollectionChanged并且是IEnumerable(例如ObservableCollection),您可以执行包装器集合。
INotifyCollectionChanged
它还可以实现CollectionChanged
。在这种情况下,您必须使用OnSourceCollectionChanged
方法中的适当参数提升WITH CTE2 AS
(
SELECT * FROM
(SELECT ID,HEAD,FACE,THOR,ABDO,SPINE
FROM PARTSDATA) T
UNPIVOT
( QUANTITY FOR PART IN
(HEAD,FACE,THOR ,ABDO , SPINE)
) AS U
),
CTE3 AS
(
SELECT RANK() OVER(PARTITION BY ID ORDER BY QUANTITY DESC) AS RN,QUANTITY,PART,ID
FROM CTE2
)
SELECT DISTINCT C1.ID,STUFF(DT.CONTENT,1,1,'') AS [AREA INJURED]
FROM CTE3 C1
CROSS APPLY(SELECT ','+PART
FROM CTE3
WHERE ID = C1.ID AND RN=1 FOR XML PATH(''))DT(CONTENT)
WHERE RN=1
事件。
您还可以创建内部List集合并公开它。在这种情况下,代理集合将具有与源集合相同的索引的代理。这取决于您的需求。