use*_*496 17 c# compare list object models
我一直在尝试和失败一段时间找到一个解决方案来比较基于对象属性的对象列表.我已经阅读了其他类似的解决方案,但它们要么不合适(或者我不理解答案!).
代码是C#
我有一个代表图像的模型
public class AccommodationImageModel
{
public int Id { get; set; }
public string Path { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public bool CoverImage { get; set; }
public bool Visible { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有两个这个模型的列表.一个是现有列表,另一个是更新列表.我需要比较两个列表,看看哪些已被删除,更新或是新的.
我不需要比较整个对象,只需在它们的属性Id上进行比较.
List<AccommodationImageModel> masterList;
List<AccommodationImageModel> compareList;
Run Code Online (Sandbox Code Playgroud)
如果compareList包含Id = 0的任何AccommodationImageModel,则它们是新的,因为新条目尚未分配Id.
如果masterList包含任何具有不在compareList中的Ids的AccommodationImageModel,那么它们将被删除,因为它们已从compareList中删除并应从masterList中删除.因此,我需要一个需要删除的列表.
如果newList和masterList具有相同的Id,那么它们将被更新.因此,我需要一个共享相同ID的列表,所以我可以更新它们.我不太关心这些模型是否相同且不需要更新,因为每个列表只会有一个小数字,所以即使它们没有改变它们也会更新并不重要.
三个结果中的每一个都需要作为AccommodationImageModel列表返回,以便我可以执行相应的更新,删除,添加.
我在下面用我选择的ATM解决方案添加了3种测试方法,展示了它的工作实现.
[TestMethod]
public void Test_Deleted_Image()
{
// set up the masterList
List<AccommodationImageModel> masterList = new List<AccommodationImageModel>();
masterList.Add(new AccommodationImageModel { Id = 1 });
masterList.Add(new AccommodationImageModel { Id = 2 });
// set up the compare list
List<AccommodationImageModel> compareList = new List<AccommodationImageModel>();
compareList.Add(new AccommodationImageModel { Id = 1 });
compareList.Add(new AccommodationImageModel { Id = 3 });
compareList.Add(new AccommodationImageModel { Id = 0 });
// get the deleted models
List<AccommodationImageModel> result = masterList.Where(c => !compareList.Any(d => d.Id == c.Id)).ToList();
// result should hold first model with id 2
Assert.AreEqual(2, result.FirstOrDefault().Id);
}
[TestMethod]
public void Test_Added_Image()
{
// set up the masterList
List<AccommodationImageModel> masterList = new List<AccommodationImageModel>();
masterList.Add(new AccommodationImageModel { Id = 1 });
masterList.Add(new AccommodationImageModel { Id = 2 });
// set up the compare list
List<AccommodationImageModel> compareList = new List<AccommodationImageModel>();
compareList.Add(new AccommodationImageModel { Id = 1 });
compareList.Add(new AccommodationImageModel { Id = 3 });
compareList.Add(new AccommodationImageModel { Id = 0 });
// get the added models
List<AccommodationImageModel> result = compareList.Where(c => c.Id == 0).ToList();
// result should hold first model with id 0
Assert.AreEqual(0, result.FirstOrDefault().Id);
}
[TestMethod]
public void Test_Updated_Image()
{
// set up the masterList
List<AccommodationImageModel> masterList = new List<AccommodationImageModel>();
masterList.Add(new AccommodationImageModel { Id = 1 });
masterList.Add(new AccommodationImageModel { Id = 2 });
// set up the compare list
List<AccommodationImageModel> compareList = new List<AccommodationImageModel>();
compareList.Add(new AccommodationImageModel { Id = 1 });
compareList.Add(new AccommodationImageModel { Id = 3 });
compareList.Add(new AccommodationImageModel { Id = 0 });
// get the updated models
List<AccommodationImageModel> result = masterList.Where(c => compareList.Any(d => c.Id == d.Id)).ToList();
// result should hold first model with id 1
Assert.AreEqual(1, result.FirstOrDefault().Id);
}
Run Code Online (Sandbox Code Playgroud)
The*_*One 23
简单的Linq
新
List<AccommodationImageModel> new = compareList.Where(c=>c.id==0).ToList();
Run Code Online (Sandbox Code Playgroud)
要删除
List<AccomodationImageModel> deleted = masterList.Where(c => !compareList.Any(d => c.id == d.id)).ToList();
Run Code Online (Sandbox Code Playgroud)
要被更新
List<AccomodationImageModel> toBeUpdated = masterList.Where(c => compareList.Any(d => c.id == d.id)).ToList();
Run Code Online (Sandbox Code Playgroud)
假设两个相同的模型Id被认为是同一个模型,你可以IEqualityComparer这样写:
public class AccommodationImageModelComparer : IEqualityComparer<AccommodationImageModel>
{
public bool Equals(AccommodationImageModel x, AccommodationImageModel y)
{
if(x == null && y == null)
return true;
return x.Id == y.Id;
}
public int GetHashCode(AccommodationImageModel model)
{
return model.Id.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用 Linq 获取所需的列表:
var comparer = new AccommodationImageModelComparer();
var newItems = compareList.Where (l => l.Id == 0).ToList();
var toBeDeleted = masterList.Except(compareList, comparer).ToList();
var toBeUpdated = masterList.Intersect(compareList, comparer).ToList();
Run Code Online (Sandbox Code Playgroud)
第一个仅过滤值为 0 的项目Id,这些项目被视为新项目。第二个查询返回 中masterList不属于 的项目compareList。最后一个查询返回两个列表中的项目。该代码可以编译但未经测试。