Alpha 0.2.3 now available

Last weekend, we did the finishing touch on the 0.2.3 release, so here it is today: please welcome LINQ to SharePoint v0.2.3.0 alpha. This is the first release to target Orcas Beta 2 and covers the following enhancements:

  • SPML has been extended and can now map lists, fields and choices on (Multi)Choice fields. The LINQ to SharePoint MSI setup registers the XSD file for SPML in the appropriate folder so you get full IntelliSense support in the VS IDE.

    image

    Also, the code generator sitting behind the SPML files in VS 2008 doesn't require any connection to the server when generating code since SPML is now fully self-describing. As a matter of fact, the SPML code generator runs in so-called "offline codegen" mode, as explained further in the SPMetal section.
  • The LINQ to SharePoint Entity Wizard is fully layered on top of the entity generator and supports enhanced list and field mapping (including the ability to set aliases on mappings to make the generated classes more user-friendly). It also support list name (English) depluralization (see below):

    image_thumb9  image_thumb10 image_thumb12 image_thumb13
  • SPMetal enhancements:

    image_thumb14
    • Full support for SPML using two times two modi: online and offline; export and codegen (but offline-export isn't meaningful). So you can do things like this:
      • Online - export: generate an SPML file for the specified list + optional context
      • Online - codegen: generates C# or VB code for the specified list + optional context (internally, it first generates the corresponding SPML)
      • Offline - codegen: takes an SPML file as the input and generates C# or VB code for it; this allows people to export SPML first (online-export), modify it and then generate code out of it
    • List name (English) depluralization. E.g. a list called Products will create an entity called Product, a list called Categories will create an entity called Category, etc.
  • Partial method support for entity properties on generated entities, both for C# and VB:

    image

    This feature will get more important once we move in the 0.3 timeframe where entity updates will be supported.
  • Grouping support; you can now write things like:

    var res = from s in ctx.Suppliers group s by s.Country;

    -or-

    var res = from s in ctx.Suppliers group s by s.Country into g select g;

    and iterate over the results as follows:

    foreach (var g in res)
    {
       Console.WriteLine(g.Key ?? "(null)");
       foreach (var s in g)
          Console.WriteLine("- {0}", s.CompanyName);
       Console.WriteLine();
    }

    image_thumb18 image_thumb16

    Furthermore, we're working on making the parser more intelligent. That's the case with grouping support as well (and it's the first place where you can see it in action), more specifically when using the IGrouping<K,T>'s Key as follows:
  • var res = from s in ctx.Suppliers group s by s.Country into g select g.Key;

    This will return the keys of the grouping, in this case all of the countries where some supplier is based. If you'd inspect this query using the debugger visualizer, you'd see that only the Country list field will be present in the query's ViewFields element. Because g.Key can only refer to the 'by'-part of the corresponding grouping operation, the parser can infer the meaning of g.Key. In the future you'll probably see more intelligende get built-in in the parser, but some of that development is done in parallel in an experimental code branch.

  • Nested Lookup field subqueries: in the past you could write things like this:

    var res = from p in ctx.Products where p.Category.CategoryName == "Beverages" select p;

    However, assume you have another list that contains orders, so you'd like to query for all of the orders of products in some category:

    var res = from o in ctx.Orders where o.Product.Category.CategoryName == "Beverages" select o;

    This didn't work in previous builds, but it does now. However, one should be vigilant when writing such queries because of the imposed runtime overhead. The query above will cause three roundtrips to the server because of CAML restrictions that are overcome by the query parser using a patching mechanism (see previous post on Lookup fields). Now we can have nested patches that are run in a depth-first manner. The code above is translated into the following query:

    image

    So, first the execution engine will go out to the server to get all of the categories that have a CategoryName equal to "Beverages". Once we've obtained the IDs for those categories, we replace the patch (<Patch Field="Category">) with a nested <Or> structure to select all of the products that match these categories. On its turn, this result is substituted in the original query as a replacement for the corresponding patch (<Patch Field="Product">). As you can imagine, these queries can get pretty large before we get to the stage of retrieving the actual query results. Nevertheless, there's no easier escape in SharePoint to do this. Here's the "query plan" for the query above:

    image

    image

    image

    There's much more to nested lookup field subqueries than you might initially think. For example, consider the query below:

    var res = from o in ctx.Orders where o.Product.Supplier.Country == "USA" && o.Product.Supplier.Region == "WA" && o.Product.ProductName.StartsWith("Ch") select o;

    In a naive query parser implementation you'd end up with as much as five patches, so a total of six roundtrips to the server:

    <And>
       <And>
          <Patch Field="Product">
             <Patch Field="Supplier">
                <Eq>
                   <FieldRef Name="Country" />
                   <Value>USA</Value>
                </Eq>
             </Patch>
          </Patch>
          <Patch Field="Product">
             <Patch Field="Supplier">
                <Eq>
                   <FieldRef Name="Region" />
                   <Value>WA</Value>
                </Eq>
             </Patch>
          </Patch>
       </And>
  •    <Patch Field="Product">
          <BeginsWith>
             <FieldRef Name="ProductName" />
             <Value>Ch</Value>
          </BeginsWith>
       </Patch>
    </And>

    Luckily, there parser is made more intelligent than this because it can join adjacent query predicate patches, resulting in this:

    <Patch Field="Product">
       <And>
          <Patch Field="Supplier">
             <And>
                <Eq>
                   <FieldRef Name="Country" />
                   <Value>USA</Value>
                </Eq>
                <Eq>
                   <FieldRef Name="State" />
                   <Value>WA</Value>
                </Eq>
             </And>
          </Patch>
          <BeginsWith>
             <FieldRef Name="ProductName" />
             <Value>Ch</Value>
          </BeginsWith>
       </And>
    </Patch>

    This is only two patches, instead of the naive five:

    image

    As a side-note, a future build will cover parser warnings that will show possible bottlenecks (as well as semantic mismatches) in the debugger visualizer. It will also be possible to control the parser's intelligence and to do a radical "treat warnings as errors" because the more intelligent some features, the more expensive these might be.

  • (Nested) LookupMulti subqueries are now supported too. In the sample above, we assumed that each of the orders in the Orders list just contains one single product reference. Of course, one might have a list that has a "multi lookup" column that refers to multiple items from another list (e.g. more than one product). Assume you have such an Orders list and you want to get all of the orders that have a product from a certain category in it:

    var res = from o in ctx.Orders where o.Products.Any(p => p.Category.CategoryName == "Beverages") select o;

    In here, the Any call - which is an extension method on System.Linq.Enumerable - is crucial because it's used as the only mechanism available to pass in a subquery predicate, in this case applied to the Products field. Again, this works with patches:

    image

    In this sample, the inner patch is corresponding to the subquery's p.Category.CategoryName Lookup field traversal, and the outer patch corresponds to the outer query's o.Products.Any call. Notice, for these kind of lookup-related constructs, an alternative implementation could be using joins but we don't have these in LINQ to SharePoint (at least not) at the moment.
  • Debugger visualizer improvements were made behind the scenes but also auto-linkage to Online F1 help information has been added: so, if you have a query problem right now, you'll be able to click on the SP**** error message and get help in the Document Explorer. However, notice that at this moment the help and documentation project is not integrated in the build yet, so you'll stumble upon invalid help documentation links in this build.
  • Code quality improvements thanks to extended coverage by code analysis and use of additional FxCop rules. However, unit test coverage is to be extended further in subsequent releases, which is a top priority in moving forward to the 0.3 timeframe. Furthermore, the code has been refactored into additional assemblies, e.g. for the debugger visualizer, to reduce the runtime workingset. In a subsequent release, the provider model will be enhanced so that people who want to use LINQ to SharePoint over web services alone don't require Microsoft.SharePoint.dll on their machine (the reason for this right now is that we depend on a few parse methods from the SharePoint Object Model, but we'll port these to be natively supported by LINQ to SharePoint).
  • The MSI Setup has improved much:
    • it's faster because we reconfigure Visual Studio 2008 in a different way
    • it registers the XSD schema of SPML
    • the .spml extension is registered with an icon and linking to devenv.exe

We hope you'll enjoy this release; keep in mind it's still alpha and send us your suggestions, comments, etc. Get it here.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Published Monday, August 13, 2007 2:00 PM by bart
Filed under:

Comments

# LINQ to SharePoint 0.2.3 alpha hits the streets

Monday, August 13, 2007 2:50 PM by LINQ to SharePoint

Released today, you can find more information on LINQ to SharePoint Alpha 0.2.3 over here . Lots of stuff

# LINQ to SharePoint 0.2.3 alpha hits the streets

Monday, August 13, 2007 5:49 PM by B# .NET Blog

Released today, you can find more information on LINQ to SharePoint Alpha 0.2.3 over here . Lots of stuff

# re: Alpha 0.2.3 now available

Tuesday, August 14, 2007 3:45 PM by Roger Jennings

Pingback from oakleafblog.blogspot.com/.../erik-meijer-to-demo-volta-for-first.html (bottom of post)

--rj

Powered by Community Server (Non-Commercial Edition), by Telligent Systems