0

I'm trying to delete items from the myDestinationList if they do not exist in the mySourceList. I'm trying to get this method done in C#. I have it set up this way because the two list are on different servers. Any suggestions?

Also would I be able to assign the Author/Editor from the source list item to the Author/Editor fields in the destination list?

Update: List has over 2k items, the client may update the list once a day or once a week, this may vary.

    static void Main(string[] args) {

      ClientContext context = new ClientContext(site2);
      List mySourceList = context.Web.Lists.GetByTitle(ListName);
      CamlQuery camlQuery = new CamlQuery();
      camlQuery.ViewXml = "<View></View>";
      ListItemCollection mySourceItemColl = mySourceList.GetItems(camlQuery);
      context.Load(mySourceItemColl);
      context.ExecuteQuery();
      SPSite myDestinationSite = new SPSite(site2);
      SPWeb myDestinationWeb = myDestinationSite.OpenWeb();
      SPList myDestinationList = myDestinationWeb.Lists[ListName2];
      SPQuery myDestinationListQuery = new SPQuery();
      myDestinationListQuery.Query = "" +
        "" +
        "" +
        "" +
        "";
      SPListItemCollection myDestinationItemColl = myDestinationList.GetItems(myDestinationListQuery);


      foreach(ListItem mySourceListItem in mySourceItemColl) {

        foreach() {
//delete items
          item.Delete();

        }


        foreach(SPListItem myDestinationListItem in myDestinationItemColl) {
//Update items here
}



      }

    }

Event Receiver

        public override void ItemAdded(SPItemEventProperties properties) {
            using(ClientContext context = new ClientContext(site1)) {
              List list = context.Web.Lists.GetByTitle(sourceList);
              CamlQuery camlQuery = new CamlQuery();
              camlQuery.ViewXml = "<View></View>";
              ListItemCollection collListItem = list.GetItems(camlQuery);
              context.Load(collListItem);
              context.ExecuteQuery();

              using(ClientContext target = new ClientContext(site1)) {
                List list2 = target.Web.Lists.GetByTitle(destinationList);
                foreach(ListItem oListItem in collListItem) {

                  ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                  ListItem AddListItem = list2.AddItem(itemCreateInfo);
                  AddListItem["Title"] = oListItem["Title"];
                  AddListItem.Update();
                  target.ExecuteQuery();
                }
              }
            }
Shark Tank
  • 25
  • 5

1 Answers1

1

How will you identify the list items? By the Title? Is this unique? You could do two things:

  1. Get all items from source list and destination. Do a Linq Query and delete the diff

This could be expensive when you have a lot of items (escpecially when you have >2000 items).

  1. Loop through the Destiantion list and check if item exists in Source list. If not, then delete

This is also an expensive task due to the fact, that Sharepoint is not like a relational database and you could loop through a list within seconds. Looping through Sharepoint Lists is time consuming.

I would preffer the first approach. But i dont know about how many items we are currently talking. Could you please update your post and give us a little more info about list sizes and how often do you need to do that action?

When you update an item, you also can assign an author to the item:

        ClientContext ctx = new ClientContext("https://...");
        List list = ctx.Web.Lists.GetByTitle("Idea");
        ListItemCollection items = list.GetItems(CamlQuery.CreateAllItemsQuery());
        ctx.Load(items); // loading all the fields
        ctx.ExecuteQuery();

        foreach (var item in items)
        {
            ctx.Load(item);
            ctx.ExecuteQuery();
            // important thing is, that here you must have the right type
            // i.e. item["Modified"] is DateTime
            FieldUserValue val = item["Old_Created_By_Person"] as FieldUserValue;

            if (val != null)
            {
                item["Author"] = val;

                // do whatever changes you want

                item.Update(); // important, rembeber changes
                ctx.ExecuteQuery();
                Console.WriteLine("Updating " + item.Id);
            }
        }
STORM
  • 4,005
  • 11
  • 49
  • 98
  • I would create sub routines for each of the possible change types SharePoint supports (Create, Update, Delete) and add code to the source list via an Event Receiver that takes the corresponding action to update the destination list. This way once you have cleaned up the destination list in batch once you will only take small, inexpensive operations to keep them in sync in the future. I've created similar solutions. STORM's code is correct, though the item properties in the event receiver are available without making a ClientContext connection to your source. – Arcan.NET Dec 30 '15 at 22:05
  • How do you call the destination site in the function(ex: public override void ItemAdded(SPItemEventProperties properties)? I have the code working as if the list were on the same site. But if I update the code, the destination list isn't update. So far I have, SPList lstOtherList = properties.Web.Lists["DestinationList"]; SPListItem item = lstOtherList.Items.Add(); item["StoredId"] = properties.ListItemId; item["Title"] = properties.AfterProperties["Title"]; item.Update(); – Shark Tank Jan 05 '16 at 19:51
  • @STORM see update to question(Event Receiver). I tried the following code with the ClientContext. Still no success. Any suggests of what I am missing? – Shark Tank Jan 06 '16 at 15:48