Two list synchronization

2019-06-05 19:25发布

问题:

I'm doing the synchronization between the two lists. IList<Event> GoogleEvents and Table<myEvent> DB.Events;

On google side i'm using this

String Summary,
String Description,
EventDateTime Start,
EventDateTime End,
Event.RemindersData Reminders;

On db side like this

my code is like this

foreach (myEvent item in DB.Events)
{
    if (item.GoogleID == "" || item.GoogleID == null)// i add event my db
    {
        //Add dbEvent to google and save id to googleid column
    }
}

foreach (Event item in myGoogleCalendar.Items)
{
    if (DB.Events.Where(o => o.GoogleID == item.Id).Count() == 0)// i add event google
    {
        //Add googleEvent to dbEvent
    }
    else
    {
        //This event also existing in two server
        myEvent dbEvent = DB.Olaylar.Where(o => o.GoogleID == item.Id).First();
        if(item.Updated.Value == dbEvent.UpdateTime) continue;//Same

        if (item.Updated.Value > dbEvent.UpdateTime)
        {
            //Google event is new 
        }
        else
        {
            //dbEvent is new 
        }

    }

}

There is one big problem : I forgot deletion

Where should I add deleting events part and how ?

回答1:

The problem is not to implement a delete synchronization, but to recognize, whether the event has been deleted in one list or added to the other list.

I recommend not to delete events from the DB.Events list, but to mark them as deleted.

Therefore, you need a flag

bool IsDeleted = false;

in your type myEvent.

In Google list (I assume you use https://developers.google.com/google-apps/calendar/v3/reference/events) you don't have such a flag. So your algorithm needs to be a bit tricky.

So you need the first synchronize from the Google list

foreach (Event item in myGoogleCalendar.Items)
{
    if (DB.Events.Where(o => o.GoogleID == item.Id).Count() == 0)
    {
        // create new DB event from Google event, because since it is 
        // not in the DB.Events list, it has not been deleted there earlier, 
        // else there would be an event with IsDeleted=true
    }
    else
    {
        //This event exists in both
        myEvent dbEvent = DB.Events.Where(o => o.GoogleID == item.Id).First();
        if (dbEvent.IsDeleted)
        {
           // delete Google event, since the flag in DB.Events list shows that 
           // it existed earlier and has been deleted in DB.Events list.
        }
        else
        {
            if(item.Updated.Value == dbEvent.UpdateTime) continue;//Same

            if (item.Updated.Value > dbEvent.UpdateTime)
            {
                // update DB event
            }
            else
            {
                // update Google event
            }
        }
    }
}

Then your synchronize from your DB.Events list

foreach (myEvent item in DB.Events)
{
    if (!item.IsDeleted && string.IsNullOrEmpty(item.GoogleID))
    {
        // Create new Google Event from DB event
    }
    else if (!item.IsDeleted && !string.IsNullOrEmpty(item.GoogleID))
    {
        // Mark DB event as deleted
        item.IsDeleted = true;
    }
}

This works in the scenarios

  • You create an event in DB
  • You create an event in Google
  • You delete an event in DB
  • You delete an event in Google


回答2:

I created a Gist: https://gist.github.com/ricjac/947991ba96488c640bfe

        // Prepare DTO to delta
        var mergeDict = DeltaExtensions.MergeDictionary(
            sourceIEnum,        //Source
            destinationIEnum,   //Destination
            s => s.SomeIdKey,
            d => d.SomeIdKey);

        // Get the delta between the two
        var mergeDelta = DeltaExtensions.GetMergeDelta(mergeDict);

        // You now have the delta of the two:
        mergeDelta.InsertedOnly
        mergeDelta.DeletedOnly
        mergeDelta.Inserted
        mergeDelta.Updated
        mergeDelta.Deleted