Could anybody help me to understand what kind of work is going behind the scene, when LINQ is used for retrieving SharePoint objects. For example, I can use a code like this:
private IEnumerable<List> newLists;
var dt = new DateTime(2010, 3, 20);
var query = from list
in clientContext.Web.Lists
where list.Created > dt && list.Hidden == false
select list;
newLists = clientContext.LoadQuery(query);
clientContext.ExecuteQuery();
How does it work?
How does request look like?
From documentation I found:
When you use the CSOM, you can write LINQ queries against client-side
objects, such as lists and Webs, and then use the ClientContext class
to submit these queries to the server. It's important to understand
that when you take this approach, you are using LINQ to Objects to
query SharePoint objects, not LINQ to SharePoint. This means that your
LINQ expressions are not converted to CAML and you will not see the
performance benefits that are associated with CAML conversion.
So, I was little bit confused, because I thought, that LINQ expression is transformed to Caml request. I can't understand how does it work. How can I watch details of request while executing ExecuteQuery() method? Could you please recomend me any tools for watching requests?
SP uses CAML internally: SP runtime converts Linq to CAML and send it via Soap request, or REST statement (if you are using RESTful services): http://msdn.microsoft.com/en-us/library/ff798339.aspx (with examples);
See more here:
http://msdn.microsoft.com/en-us/library/ff798464.aspx
and this can be helpful: http://nikspatel.wordpress.com/2012/08/05/sharepoint-2010-data-querying-options-server-om-vs-client-om-vs-rest-vs-linq-vs-search-api/
Related
I have an ASP.Net Core RESTful API with an End-point that returns a IQueryable<dynamic> type.
If OData's $filter or $select is not used in the URI, the data is returned correctly.
Because of the dynamic nature of the data, I cannot strongly type the endpoints result.
Is there a way to use OData's $filter and $select here?
My API is using the Dapper ORM. I am considering converting over to Entity Framework Core since it works very well with OData. But, if I can continue to use the Dapper ORM, it would save me refactoring a lot of code.
The application uses a lot of complex SQL statements that I would like to continue to use to avoid further refactoring.
If I build a "Business Object" for each of my complex queries, Dapper works fine with OData. The only draw back is that the data is flattened. This means the programmer of the Client consuming the API cannot implement OData's $expand statement. But, we can get by with flattened master/detail data if we need to.
So, in my attempt to build an end-point for each of these complex queries, I decided to try and return an IEnumerable or IQueryable (both work) of the dynamic type so I would not have to write a Business Object (or Model) for each of our complex queries.
The .NET Core CLR accepts the dynamic type results and converts it to JSON successfully for the most part, except for $expand as noted above.
Sorry for the late response, but I had to re-write one of my end-points so our real logic was not exposed. I kept the nature of what I'm trying to do in a generic way. My Repository object is just the Dapper ORM shrink-wrapped for our business purposes. Thanks in advance for your help.
[HttpGet("[action]")]
[EnableQuery]
public ActionResult<IQueryable<dynamic>> GetComplex()
{
string sql = "SELECT master.*, detail1.*, detail2.* " +
"FROM MasterTable AS master " +
"LEFT JOIN FirstDetailTable AS detail1 " +
" ON master.Id = detail1.MasterId " +
"LEFT JOIN SecondDetailTable AS detail2 " +
" ON master.Id = detail2.MasterId " +
"ORDER BY master.SomeColumn";
string myDB_CatalogName = "MyCatalog";
int commandTimeOut = 30;
Repository<dynamic> repository = new Repository<dynamic>(_dbConnectionString, myDB_CatalogName, commandTimeOut);
IQueryable<dynamic> myQueryResults = repository.ExecuteSqlStatement(sql).AsQueryable();
return Ok(myQueryResults);
}
I'm trying to query RavenDB using the HTTP client for all documents by type.
I would like a collection of the documents with a given type.
I understand that there might be limitations only the first 1024 documents will be returned.
I am well under that number and besides it's for a proof of concept.
I am able to obtain all the documents using the following syntax:
http://localhost:8080/databases/{database name}/docs/
I see that I could use the #metadata field to get the documents of the type I want but I don't know the syntax.
Since the HTTP api allows you to query indexes, I attempted to write a static index.
When I wrote the index from Raven Studio, the index was not returning the documents of the type I wanted. It was giving zero results.
from doc in docs.MyType
select new { doc};
I also tried this:
from doc in docs
let Tag = doc["#metadata"]["Raven-Entity-Name"]
where Tag == "MyType"
select new { doc};
You can do it using:
http://localhost:8080/databases/{database name}/indexes/dynamic/CollectionName
I am starting to develop a system using silverlight 5 with wcf ria. I use Visual studio 2010 and the code is in visual basic. In my application I have a table guiasidiomas. It is a very simple table:
Id
Idguia
Ididioma
In the application I changed the query getguiasidiomas that is generated by the domain service
Public Function GetGuiasIdiomas(ByVal idProcurado As String) AsIQueryable(Of GuiasIdioma)
Return Me.ObjectContext.GuiasIdiomas.Where(Function(c) (c.idGuia).ToString = idProcurado)
End Function
I inserted a where in order to filter by a given idguia.
That is the query that has a problem.
If you could help me I would appreciate very much.
When I run the query I get:
SCRIPT5022: Unhandled Error in Silverlight Application
Code: 4004
Category: ManagedRuntimeError
Message: System.ServiceModel.DomainServices.Client.DomainOperationException: Load operation failed for query 'GetGuiasIdiomas'. LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
Linq-to-Entities cannot translate .ToString() directly to SQL, so you cannot use it in your WHERE clause. Here are two options:
Convert idProcurado to the same datatype as idGuia and compare directly
Pull ALL entities from the database (e.g. by calling .AsEnumerable()) and doing the comparison against the object list.
I'm guessing 1) is going to give you better performance by only puling back one or a small number of entities.
As your error message says, linq to entities does not support ToString.
You can prepare list of strings before using it with linq to entities.
I am a new to using Mongo DB and exploring the frameworks around for migrating from mysql to mongodb. So far from my findings I have been able to figure out SpringMongo as the best solution to my requirements.
The only problem is that instead of using a DSL based or abstract querying mechanism, I wished the framework allowed me to pass plain json string as arguments to the different methods exposed by the API(find, findOne) so that the query parameters can be written out to an external file (using a key to refer) and passed to the methods by reading and parsing at run time. But the framework should be capable of mapping the results to the domain objects.
Is there a way in spring-mongo to achieve this? Or is there any other frameworks on the same lines
You could use Spring Data to do that, just use the BasicQuery class instead of Query class. Your code will look like the following:
/* Any arbitrary string that could to parsed to DBObject */
Query q = new BasicQuery("{ filter : true }");
List<Entity> entities = this.template.find(q, Entity.class);
If you want more details:
http://static.springsource.org/spring-data/data-mongo/docs/current/reference/html/#mongo.query
http://static.springsource.org/spring-data/data-mongodb/docs/current/api/org/springframework/data/mongodb/core/query/BasicQuery.html
Well I got to find this one in the Spring data MongoOperations...
String jsonCommand = "{username: 'mickey'}";
MongoOperations mongoOps = //get mongooperations implemantation
mongoOps.executeCommand(jsonCommand)
It returns an instance of CommandResult that encapsulates the result.
I want to make custom select from the database table using Linq. We use LLBGEN as ORM solution.
I can't do LINQ query to Entities Collection Class unless I call GetMulti(null) method of it.
Is it possible to do LINQ query to LLBGEN without extracting all table first?
BatchCollection batches = new BatchCollection();
BatchEntity batch = batches.AsQueryable()
.Where(i => i.RegisterID == 3)
.FirstOrDefault(); // Exception: Sequence don't contains any elements
batches = new BatchCollection();
batches.GetMulti(null); // I don't want to extract the whole table.
BatchEntity batch = batches.AsQueryable()
.Where(i => i.RegisterID == 3)
.FirstOrDefault(); //Works fine
To query your database using LINQ (which is different from operating on an enumerable collection using the LINQ syntax) you have to use the LinqMetaData provider that comes with LLBLGen in the yourrootnamespace.Linq assembly. Once you add this assembly to your project you can use something like this to create your db query: (from the LLBL documentation)
LinqMetaData metaData = new LinqMetaData();
var q = from c in metaData.Customer
where c.Country=="USA"
select c;
In your example above you are using LINQ syntax to perform a where clause on a collection, but this does not have anything to do with LLBL or executing a query on the database. That is why it will not work with the empty collection, but does work on the filled collection.
Look more into LinqMetaData for the specifics of querying your db using LINQ to LLBLGen.