This is to show the basic outline of code to add an attachment to a list in sharepoint, I made a page with System.Web.UI.WebControls.FileUpload on it and used the control’s FileBytes property to get an array of bytes. so the call to this function will look like this 

addAttachment("title text","filename.txt",fileuploadControl.FileBytes);

the code to add the attacment to the list will look like this

public static void addAttachment(string title,string filename,byte[] fil)
{

        using (SPSite site = new SPSite("https://site"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList list = web.Lists["SomeList"];
                SPQuery query = new SPQuery { RowLimit = 0 };
                SPListItem listItem = list.GetItems(query).Add();
                listItem.Web.AllowUnsafeUpdates = true;

                //title field in the list
                listItem.Title = title;

                //add the attachment to the list
                SPAttachmentCollection attachments = listItem.Attachments;
                attachments.Add(filename, fil);

                listItem.Update();
                list.Update();
                web.Update();
            }
        }
}

basicly, you query the list with rowlimit = 0 to avoid to get all items in the items object, and then use the SPAttachmentCollection to add the file you want to attach with the appropriate filename.

I got the useal phone call today from a customer “I tried to change the user details but something went wrong and now i can’t change his details”. I checked the profile import and realized it had been running for 18 days. same thing with search… did the useal google search, and only thing i could find where problems with sql server and not having sp2. It was not the case on this server everything where updated with latest. Another one suggested maintenance plan on the search db could cause some hick ups but no maintenance plan on the db where exsisting. so i tried to stop the profile import.. nothing happened, then i tried to stop the search crawl, nothing.

then the next step where to kill the service, I realized two services where present, one for WSS(Windows Sharepoint Services Search) and one for MOSS(Office Sharepoint Server Search)   both where running. i killed the wss service first no problem with that one. then tried the same thing with the MOSS one and it couldn’t stop! ofcourse it couldnt be started either…

in a bit of a deadlock both me and the server i had to go into the taskmanager and kill all the processes related to Office Sharepoint Server Search, then the cpu hit the roof and all memory where swallowed for 5 minutes and suddenly everything where calm. went into the shared services administration thing and re ran the profile import and everything where fine. I am going to watch this server carefully the following days but what could have caused this I have no clue, anyone got answer?

I have been struggling with large lists for some time now, and the need to look at performance in queries where early an issue within a particular project of mine. It all started out with a small list of a couple of thousand items but soon grew to 60k and still growing. The work to fine tune the queries to this list have been going on over a couple of months since everything gradually slowed down. I will try and share some of the things I tried to implement during the developing phase. The queries now run 3 times faster than my previous release and this is due to a number of reasons.

The code

It’s a straight forward query to a list in Sharepoint which contain price information which again is used to validate invoices on external files.

        public class PrisDef
        {
            public string Place { get; set; }
            public string Contract { get; set; }
            public decimal MaxPris { get; set; }
            public decimal MinPris { get; set; }
            public decimal Pris { get; set; }
            public string SKU {get; set;}
            public string InUse { get; set; }
        }

        public static List<PrisDef> GetPris(string SKU)
        {
            List<PrisDef> priser = new List<PrisDef>();

            XmlDocument camlDocument = new XmlDocument();
            camlDocument.LoadXml(@"<Where>
                                <Eq>
                                    <FieldRef Name='SKU' />
                                    <Value Type='Integer'>[SKU]</Value>
                                </Eq>
                            </Where>".Replace("[SKU]", SKU));

            using (SPSite site = new SPSite("https://site"))
            {
                using (SPWeb web = site.OpenWeb())
                {

                   SPQuery query = new SPQuery();
                   query.Query = camlDocument.InnerXml;
                   query.RowLimit = 1000;
                   SPListItemCollection items = web.Lists["Price"].GetItems(query);

                   IEnumerable<PrisDef> sortedItems =
                   from item in items.OfType<SPListItem>()
                   select new PrisDef
                   {
                        Contract = arseString(item["Contract"]),
                        Place = parseString(item["Place"]),
                        Pris = parseDecimal(item["Pris"]),
                        SKU = parseString(item["SKU"]),
                        MaxPris = parseDecimal(item["MaxPris"]),
                        MinPris = parseDecimal(item["MinPris"]),
                        InUse = parseString(item["Use"])
                    };

                        priser.AddRange(sortedItems);

                        return priser;
                    }
                }
            }

                    

A couple of points to notice within the code.

Dispose both spsite and spweb, this is to avoid memory leaks, look at article:

                http://msdn.microsoft.com/en-us/library/aa973248.aspx

Set rowlimit, this is to avoid lock on a table article

                 An SPQuery object without a value for RowLimit will perform poorly and fail on large lists. Specify a RowLimit between 1 and 2000 and, if necessary, page through the list.

                  http://msdn.microsoft.com/en-us/library/bb687949.aspx

the more intresting part is to look at what not todo.:

never use Items, SPList.Items returns all the items in a list and performs badly especially on a large list. I found this especially usefull in tweaking an writing to a list. Notice that I start with a query which return 0 rows, this to avoid items which would have returned the whole list.

            using (SPSite site = new SPSite("https://site"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList list = web.Lists["Log"];
                    SPQuery query = new SPQuery { RowLimit = 0 };
                    SPListItem listItem = list.GetItems(query).Add();

                    listItem.Web.AllowUnsafeUpdates = true;
                    listItem["Errorlog"] = feilMelding;

                    listItem.Update();
                    list.Update();
                    web.Update();
                }
            }

Iwould also like to refer to the list of alternatives for SPList.Items on msdn http://msdn.microsoft.com/en-us/library/bb687949.aspx

Alternatives to SPList.Items

Poor Performing Methods and Properties Better Performing Alternatives
SPList.Items.Count SPList.ItemCount
SPList.Items.XmlDataSchema Create an SPQuery object to retrieve only the items you want.
SPList.Items.NumberOfFields Create an SPQuery object (specifying the ViewFields) to retrieve only the items you want.
SPList.Items[System.Guid] SPList.GetItemByUniqueId(System.Guid)
SPList.Items[System.Int32] SPList.GetItemById(System.Int32)
SPList.Items.GetItemById(System.Int32) SPList.GetItemById(System.Int32)
SPList.Items.ReorderItems(System.Boolean[],System.Int32[],System.Int32) Perform a paged query by using SPQuery and reorder the items within each page.
SPFolder.Files.Count  

This is a start, I will try to cover a couple of other topics within performance on large Lists. This is my first blogpost enjoy.

Follow

Get every new post delivered to your Inbox.