Il comando SPMETAL (...14\bin\SPMETAL.EXE) di SharePoint 2010 permette di generare una classe wrapper di accesso alle liste di un sito. La classe generata può essere usata per elencare il contenuto di liste, cercare item tramite LINQ, aggiungere, rimuove e cancellare item.

La sintassi del comando è:
DOS / Batch file
PS C:\Users\Administrator> SPMETAL.EXE /web:http://intranet.contoso.com /code:Test.cs /namespace:Sgart.Metal
la classe generata è simile a questa:
C#
namespace Sgart.Metal
{
  using System;

  public partial class TestDataContext : Microsoft.SharePoint.Linq.DataContext
  {

    #region Extensibility Method Definitions
    partial void OnCreated();
    #endregion

    public TestDataContext(string requestUrl) :
      base(requestUrl)
    {
      this.OnCreated();
    }

    /// <summary>
    /// Use this list to track upcoming events, status updates or other team news.
    /// </summary>
    [Microsoft.SharePoint.Linq.ListAttribute(Name = "Announcements")]
    public Microsoft.SharePoint.Linq.EntityList<Announcement> Announcements
    {
      get
      {
        return this.GetList<Announcement>("Announcements");
      }
    }
...
  [Microsoft.SharePoint.Linq.ContentTypeAttribute(Name = "Item", Id = "0x01")]
  [Microsoft.SharePoint.Linq.DerivedEntityClassAttribute(Type = typeof(Announcement))]
...
  public partial class Item : Microsoft.SharePoint.Linq.ITrackEntityState, Microsoft.SharePoint.Linq.ITrackOriginalValues, System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.INotifyPropertyChanging
  {

    private System.Nullable<int> _id;

    private System.Nullable<int> _version;

    private string _path;

    private Microsoft.SharePoint.Linq.EntityState _entityState;

    private System.Collections.Generic.IDictionary<string, object> _originalValues;

    protected string _title;

    #region Extensibility Method Definitions
    partial void OnLoaded();
    partial void OnValidate();
    partial void OnCreated();
    #endregion
...
  [Microsoft.SharePoint.Linq.ContentTypeAttribute(Name = "Announcement", Id = "0x0104")]
  public partial class Announcement : Item
  {

    private string _body;

    private System.Nullable<System.DateTime> _expires;

    #region Extensibility Method Definitions
    partial void OnLoaded();
    partial void OnValidate();
    partial void OnCreated();
    #endregion

    public Announcement()
    {
      this.OnCreated();
    }

    [Microsoft.SharePoint.Linq.ColumnAttribute(Name = "Body", Storage = "_body", FieldType = "Note")]
    public string Body
    {
      get
      {
        return this._body;
      }
      set
      {
        if ((value != this._body))
        {
          this.OnPropertyChanging("Body", this._body);
          this._body = value;
          this.OnPropertyChanged("Body");
        }
      }
    }
...

Ecco un esempio di utilizzo in una console application (impostare la compilazione a MSIL o x64)
C#
#c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.SharePoint.dll
#c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.SharePoint.Linq.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sgart.Metal;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      string url = "http://intranet.contoso.com";
      using (TestDataContext dc = new TestDataContext(url))
      {
        Separator("Start");
        FindAllEvents(dc);

        Separator("Insert");
        DateTime dt = DateTime.Now.AddHours(1);
        InsertEvent(dc, "title 2", dt, dt.AddHours(2));
        FindEvent(dc, "prova");

        Separator("Update");
        dt = dt.AddDays(1);
        UpdateEvent(dc, "prova", dt, dt.AddHours(3));

        Separator("Delete");
        DeleteEvent(dc, "prova 3");

        Separator("before commit");
        FindAllEvents(dc);

        //commit all changes
        dc.SubmitChanges();

        Separator("After commit");
        FindAllEvents(dc);
      }
    }

    private static void Separator(string message)
    {
      Console.WriteLine("- " + message + " ----------------------------------");
    }

    private static void FindAllEvents(TestDataContext dc)
    {
      foreach (var item in dc.Calendar)
      {
        Console.WriteLine(item.Title + " - " + item.StartTime + " - " + item.EndTime);
      }
    }

    private static CalendarEvent FindEvent(TestDataContext dc, string name)
    {
      var item = dc.Calendar.FirstOrDefault(q => q.Title.StartsWith(name, StringComparison.InvariantCultureIgnoreCase));
      if (item != null)
      {
        Console.WriteLine(item.Title + " - " + item.StartTime + " - " + item.EndTime);
      }
      else
      {
        Console.WriteLine("Not Found: " + name);
      }
      return item;
    }

    private static void InsertEvent(TestDataContext dc, string title, DateTime startTime, DateTime endTime)
    {
      CalendarEvent item = new CalendarEvent()
      {
        Title = title,
        StartTime = startTime,
        EndTime = endTime
      };
      dc.Calendar.InsertOnSubmit(item);
    }
    
    private static void UpdateEvent(TestDataContext dc, string name, DateTime startTime, DateTime endTime)
    {
      var item = FindEvent(dc, name);
      if (item != null)
      {
        item.StartTime = startTime;
        item.EndTime = endTime;
      }
      else
      {
        Console.WriteLine("Not Found: " + name);
      }
    }

    private static void DeleteEvent(TestDataContext dc, string name)
    {
      var item = FindEvent(dc, name);
      if (item != null)
      {
        dc.Calendar.DeleteOnSubmit(item);
      }
      else
      {
        Console.WriteLine("Not Found: " + name);
      }
    }

  }
}

che genera il seguente output
Text
- Start ----------------------------------
Prova - 6/21/2012 12:46:48 AM - 6/21/2012 3:46:48 AM
title - 6/4/2012 7:38:00 AM - 6/4/2012 1:38:00 PM
prova 3 - 6/19/2012 9:42:00 AM - 6/19/2012 11:42:00 AM
- Insert ----------------------------------
Prova - 6/21/2012 12:46:48 AM - 6/21/2012 3:46:48 AM
- Update ----------------------------------
Prova - 6/21/2012 12:46:48 AM - 6/21/2012 3:46:48 AM
- Delete ----------------------------------
prova 3 - 6/19/2012 9:42:00 AM - 6/19/2012 11:42:00 AM
- before commit ----------------------------------
Prova - 6/8/2012 12:47:43 AM - 6/8/2012 3:47:43 AM
title - 6/4/2012 7:38:00 AM - 6/4/2012 1:38:00 PM
prova 3 - 6/19/2012 9:42:00 AM - 6/19/2012 11:42:00 AM
- After commit ----------------------------------
Prova - 6/8/2012 12:47:43 AM - 6/8/2012 3:47:43 AM
title - 6/4/2012 7:38:00 AM - 6/4/2012 1:38:00 PM
title 2 - 6/7/2012 12:47:43 AM - 6/7/2012 2:47:43 AM
Tutte le modifiche vengono committate solo alla fine quando viene invocato il metodo SubmitChanges del data context

Vedi anche: SPMetal e Using LINQ to SharePoint
Potrebbe interessarti anche: