I have a document libraries. I want to filter the documents based on some of the filter conditions. Its really difficult to generate the Caml query dynamically which will give the actual result depending on the filter values.
The filter values are the columns from Document libraries. Linq to Sharepoint support List, but is there anyway by which i can query document libraries too?
You can use Linq To Sharepoint after using the SPMetal tool to generate your entities.
http://www.codeproject.com/Articles/399927/SharePoint-2010-LINQ-and-SPMetal
This is an example of what Sharepoint Link looks like:
using (SiteEntitiesDataContext context = new SiteEntitiesDataContext("http://appes-pc"))
{
var result = context.Manager.Where(m => m.Country == "USA");
foreach (ManagerItem manager in result)
{
Console.WriteLine(manager.Name);
}
}
Or alternatively if you want to use CAML there is a very good CAML builder utility called:
Camlex.NET - http://camlex.codeplex.com/
So this:
<Where>
<Eq>
<FieldRef Name="Status" />
<Value Type="Text">Completed</Value>
</Eq>
</Where>
Can be written as:
string caml =
Camlex.Query()
.Where(x => (string)x["Status"] == "Completed").ToString();
Related
I've poured through various articles but haven't found an answer to my exact scenario. I've a SharePoint 2010 list with some Query Parameters for filter purposes. My CAML Query works well for filtering except in one circumstance, I'd like a General Display All criteria in my query for when the listview is first hit (i.e. my client will actively be able to see/page/sort the data without first having to search the list).
If I was just filtering the list fields I'd be set, but since I'm referencing Query Parameters in my CAML I'm receiving SOAP errors in SharePoint Designer.
The SQL equivalent would be: Where (#Parameter1 is null and #Parameter2 is null and #Parameter3 is null...)
I've tried this structure:
<Or Group="true">
<And>
<And>
<IsNull>
<FieldRef Name ="Title"/>
<Value Type="Text">{RollNum}</Value>
</IsNull>
<Gt>
<FieldRef Name="ID"/>
<Value Type="Counter">
<IfEqual>
<Expr1><![CDATA[{Param1}]]></Expr1>
<Expr2/>
<Then>0</Then>
<Else>2147483647</Else>
</IfEqual>
</Value>
</Gt>
</And>
<IsNull>
<FieldRef Name ="RefNumber"/>
<Value Type="Text">{RefNum}</Value>
</IsNull>
</And>
</Or>...the rest of the query, which works fine.
I have a feeling my structure is incorrect.
Thanks in advance,
Brian H.
You can use this syntax to determine if a field is null:
<Where><IsNull><FieldRef Name='YourFieldName' /></IsNull></Where>
You have an extra Value element within IsNull that you should remove.
I decided to use an HTML Form Web Part to achieve my goal (instead of a content editor). The HTML form web part keeps all filter values entered into any boxes, and can be wired up to filter my list using parameters and a custom caml query.
I'm having problem with querying IEnumerable computed index field. Im using Sitecore 7.2 upd2, Lucene, ContentSearch and PredicateBuilder.
I'm trying to query product prices which are available under products section. There is some heavy Logic to find available products so I decided to put all available product prices in computed field. Unfortuantelly it looks like I'm unable to query prices list with PredicateBuilder.
My query looks like this:
predicate = predicate.And(p => p.Prices.Any(x => x >= priceFrom && x <= priceTo));
field configuration in index config:
<field fieldName="Prices" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" type="System.Collections.Generic.IEnumerable`1[System.Int32]" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />
and that's my error:
Invalid Method Call Argument Type: Field - FieldNode - Field: prices - System.Collections.Generic.IEnumerable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]. Only constant arguments is supported.
Any Ideas?
The error stems from parameter of the Any() method call.
Sitecore Content Search LINQ has some limitations. One of them is that methods only accept "constant expressions" (objects) as parameters. You are passing a "lamda expression" as a parameter for the Any method.
I would suggest indexing both the min and max price for each product as separate computed fields (decimal) in the index.
This would greatly simplify your query:
var results = context.GetQueryable<ProductSearchResultItem>
.Where(p => p.MinPrice >= myPrice)
.Where(p => p.MaxPrice <= myPrice)
.GetResults();
I have a large document library (at the moment ~6000 documents) and I need to find a document based on a custom field value (custom column on the library).
Is there a way of getting this document back without iterating through all 6000 documents?
I understand that an iteration must occur at some point, but I would prefer it to happen on the SharePoint server side, rather than transfer them all to the client side then cherry pick the document.
Thanks
You can query Sharepoint. You issue a CAML query which is executed on the server and brings back only items that match the criteria that you specified. You specify the name of the custom column to search on and you specify the value to find. For efficiency , you can ask only for a few fields back (document url for example). So, you do not need to iterate over documents in the list to find the item.
You can find some discussion here:
http://msdn.microsoft.com/en-us/library/ee956524.aspx and you can also find examples how to do it from javascript or silvelight.
Example CAML:
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml =
#"<View>
<Query>
<Where>
<Eq>
<FieldRef Name='FileLeafRef'/>
<Value Type='Text'>Test.docx</Value>
</Eq>
</Where>
<RowLimit>1</RowLimit>
</Query>
</View>";
Example, I have some groups and some items belong to these group. Now, I want to list items of arbitrary group by url like http://sp2010/Lists/items.aspx?groupid=1.
I maked a SPView like
SPView view = SPList.DefaultView;
view.Query = "<Where>
<Eq>
<FieldRef Name=\"Group\" LookupId=\"TRUE\">
<Value Type=\"Lookup\"><GetVar Name=\"GroupId\"></Value>
</Eq>
</Where>";
view.Update();
It work on sharepoint 2007, but unfortunately it don't work on sharepoint 2010.
Try FilterField and FilterValue:
http://sp2010/Lists/MyList/AllItems.aspx?FilterField1=group&FilterValue1=Group%20Name
Note that the value of FilterField is the internal name of the field, not the display name.
If I have a mapping like this:
<class name="Library" table="Libraries">
...
<dynamic-component name="Annotations">
<property name="LibraryResolver.AlgorithmVersion" column="`LibraryResolver.AlgorithmVersion`" type="Int32" />
</dynamic-component>
</class>
How should I write HQL or Linq-to-NHibernate query for all libraries where LibraryResolver.AlgorithmVersion is greater than a given value?
The HQL query below maybe along the lines you are looking for
from Library as lib
where lib.Annotations.LibraryResolver.AlgorithmVersion > 2
If you're using nhibernate, have you tried out the NHibernate LambdaExtensions? This library provides a set of extensions methods over the Criteria and DetachedCriteria apis which removes the need of magic strings when querying using the above two api.
Below is an example of how one might use NHibernate Detached Criteria query with the mentioned LambdaExtensions library
Answer answerAlias = null;
var actual = DetachedCriteria.For<Survey>()
.Add<Survey>( s => s.Status == SurveyStatus.Complete )
.Add<Questionnaire>( q => q.Id == questionnaireId )
.CreateAlias<Survey>( s => s.Answers, () => answerAlias )
.SetProjection( LambdaProjection.Property( () => answerAlias.Id ) );
I don't know whether this helps but when I use the Criteria API (in Java) it just works. Haven't tried with HQL though.
<dynamic-component name="values">
<property name="dynamicNameValue" column="ATTRIBUTE_1" type="string"/>
<property name="dynamicNumber" column="ATTRIBUTE_4" type="integer"/>
</dynamic-component>
Criteria criteria = session.createCriteria(DynamicAttributes.class)
.add(Expression.eq("values.dynamicNumber", 2));
Just some thought: could it be that the problem is that the name ('LibraryResolver.AlgorithmVersion') you're passing contains a dot? Maybe post some code you already attempted?