简体   繁体   中英

Comparing LINQ entities and getting difference

I'm writing synchronization system for my database with flash drive. So, there is xml file on flash with content got by GUID of entity.

I'm using standart XmlSerialize and DataLoadOptions for serialization base and related entities.

So, I need implement comparator to get difference between database data and deserialized data from flash drive.

I tried to use Linq Except<> method, but it says that same entities are different.

Is there anothere way to compare entities and get object, that contains different data?

You can create your own method for that. Let's say you have :

interface IEntity
{
    int Id { get; set; }
}

And concrete class that implements it:

class Entity : IEntity
{
    public int Id { get; set; }
}

You can create method like this :

    static ICollection<T> Compare<T>(ICollection<T> list1, ICollection<T> list2) where T : IEntity
    {
        List<T> result = new List<T>();
        foreach (T item in list1) if(!list2.Any(e => e.Id == item.Id)) result.Add(item);
        foreach (T item in list2) if (!list1.Any(e => e.Id == item.Id)) result.Add(item);
        return result;
    }

Usage :

List<IEntity> list1 = new List<IEntity>() { new Entity() { Id = 1 }, new Entity() { Id = 10 } };
List<IEntity> list2 = new List<IEntity>() { new Entity() { Id = 1 }, new Entity() { Id = 5 } };

List<IEntity> result = Compare(list1, list2).ToList();

foreach (IEntity item in result)
{
    Console.WriteLine(item.Id);
}

Output : 5, 10

PS It should be ok in terms of performance but if you still want to use LINQ - try to implement IEqualityComparer interface and pass instance of it to .Except() method as a second overload.

This trick may or may not be applicable in your case, but I'm sharing this in case someone finds it useful.

You can use automapper to map the entity that came from xml to the entity that came from the DB. (You would need to load your entities from the db to memory first).

EF is smart enough to detect when updated property values match original and not mark these entities as dirty. You can then examine the entity state, and if it's unchanged, then the entities match.

if (myDbContext.Entry(entity).State != EntityState.Unchanged) 
... etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM