Skip to content

LINQ support

misonou edited this page Sep 14, 2016 · 5 revisions

The IQueryable interface of SPModel-to-LINQ can be get by SPModelManger.Query() extension method.

SPModelManger<MyItem> manager = new SPModelManger<MyItem>(web);
IQueryable<MyItem> queryable = manager.Query();

foreach (MyItem item in queryable.Where(x => x.Enabled)) {
    // ...
}

Supported expressions

Expression Equivalent CAML Element LINQ Example
Equals <Eq>...</Eq> .Where(x => x.Prop == value)
Not equals <Neq>...</Neq> .Where(x => x.Prop != value)
Greater than or equal <Geq>...</Geq> .Where(x => x.Prop >= value)
Greater than <Gt>...</Gt> .Where(x => x.Prop > value)
Less than or equal <Leq>...</Leq> .Where(x => x.Prop <= value)
Less than <Lt>...</Lt> .Where(x => x.Prop < value)
In <In>...</In> .Where(x => values.Contains(x.Prop))
Includes <Includes>...</Includes> .Where(x => x.Prop.Contains(value))
Not includes <NotIncludes>...</NotIncludes> .Where(x => !x.Prop.Contains(value))
Is null <IsNull>...</IsNull> .Where(x => x.Prop == null)
Is not null <IsNotNull>...</IsNotNull> .Where(x => x.Prop != null)
Begins with <BeginsWith>...</BeginsWith> .Where(x => x.Prop.StartsWith(value))
Content type ID begins with <BeginsWith>...</BeginsWith> .Where(x => x is T)
.OfType<T>()
Logical AND <And>...</And> .Where(x => P1 && P2)
.Where(x => P1).Where(x => P2)
Logical OR <Or>...</Or> `.Where(x => P1
Logical NOT <Not>...</Not> .Where(x => !P1)
Order by <OrderBy>...</OrderBy> .OrderBy(x => x.Prop)
.OrderByDescending(x => x.Prop)
.ThenBy(x => x.Prop)
.ThenByDescending(x => x.Prop)
Row limit <RowLimit /> .Take(limit)
Skip - .Skip(skip)

Note: The value type is determined by the property type as well as attribute type. See Choosing attribute and property type for more information.

Dealing with lookup fields

For lookup (and user) fields, generally in model classes they are defined as properties with type SPPrincipal and SPModel and their collection types.

To query against these fields, you can compare them directly by == or !=, or by compare their ID:

// attributes omitted for simplicity
public abstract class MyItem : SPModel {
    public abstract SPPrincipal UserField { get; set; }
    public abstract ICollection<PPrincipal> MultiUserField { get; set; }
    public abstract MyItem LookupField { get; set; }
    public abstract ICollection<MyItem> MultiLookupField { get; set; }
}

// example of user field
query.Where(v => v.UserField == currentUser);
query.Where(v => v.UserField.ID == currentUser.ID);
query.Where(v => v.MultiUserField.Contains(currentUser));

// example of lookup field
query.Where(v => v.LookupField == anotherModel);
query.Where(v => v.LookupField.GetMetaData().ID == anotherModel.GetMetaData().ID); 
query.Where(v => v.MultiLookupField.Contains(anotherModel));

Querying property of other types

Properties defined on the model class may return other types that are not associated to any field types for high usability.

By default the library does not know how to handle these property types. To enable querying on these properties, use the SPModelQueryPropertyAttribute attribute class.

[SPContentType(...)]
public abstract class MyItem : SPModel {
    [SPGuidField("LookupListID")]
    [SPModelQueryProperty(typeof(SPList), "ID")]
    public SPList LookupList {
        get { return this.Adapter.Web.Lists[this.Adapter.GetGuid("LookupListID")]; }
    }
}

var manager = new SPModelManager<MyItem>(web)
manager.Query().Where(x => x.LookupList == list);