I have created a query expressions which retrieves all order products associated with an order.
Here is my current query expression:
var query = new QueryExpression("salesorderdetail");
query.ColumnSet = new ColumnSet(new string[] { "salesorderdetailid", "productid", "new_event", "new_inventory", "productdescription" });
query.Criteria.AddCondition("salesorderid", ConditionOperator.Equal, combinedEntity.Id);
query.Distinct = true;
EntityCollection retrieved = context.OrganizationService.RetrieveMultiple(query);
The problem is that I only want to retrieve data with a unique productid.
Is this possible using QueryExpression? Can anyone show me?
Many thanks.
I am not 100% sure what you are asking, however there is a trick I like to use that may help when writing query expressions:
Navigate to the view that displays the records in question
Click the Advanced Find button in the Ribbon Bar
Configure your “find” until it shows the records you are looking for
Click the Download Fetch XML button in the Ribbon Bar
Open the file with a text viewer (or your fav dev tool)
While this is not “code” per se, it usually contains some good hints on how to write it. Also, there is the option of using a Fetch XML query in your code as well.
Use FetchXML to Construct a Query
http://msdn.microsoft.com/en-us/library/gg328117.aspx
If you just need the distinct set of ProductIds contained within the sales order, couldn't just remove the other columns from the ColumnSet? Like so:
query.ColumnSet = new ColumnSet(new string[] { "productid" });
Related
Is there a way to build a QueryExpression returning just a particular set of records?
I have the following Criteria Types:
First:
Returns the first n Records (i.e. select top)
Last:
Returns the last n records
Every:
Returns every n'th record
For the type "First" I can use
queryExpression.TopCount = number_of_records
But I have no Idea how I can achieve the other types of criteria. The issue is that there are quite big data volumes and if I need first to get all records and query the result for example with Linq to customize the resultset I will probably have a performance issue.
If I could build the QueryExpression just selecting exactly what I need the whole thing gets more efficient.
Does anybody have an idea on how to achieve this with a QueryExpression?
The system in question is Microsoft Dynamics CRM Online
For the "last N" you can reverse the sort and use TopCount again.
For the "every Nth" you might want to consider paging the Query Expression.
Say you're looking for every 10th record. What I might do would be to set my page size to 10 (query.PageInfo.Count).
To iterate through the pages as quickly as possible I'd make my "main" query return only the GUIDs. When I retrieve a new page of GUIDs, I'd grab the first GUID and get the columns I want for that record using a separate Retrieve call.
Last N Records: quite simple order by particular field as descinding and then top N that's it
Returns the last n records
// Instantiate QueryExpression QEaccount
var QEaccount = new QueryExpression("account");
QEaccount.TopCount = 5;
// Add columns to QEaccount.ColumnSet
QEaccount.ColumnSet.AddColumns("name", "ah_account_type", "accountid");
QEaccount.AddOrder("name", OrderType.Descending);
Every nth Record:
Do you have any particular criteria here, for example give me all accounts where country =Germany
if yes then you can user condition to return particular set of records as below
// Define Condition Values
var QEaccount_address1_country = "Germany";
// Instantiate QueryExpression QEaccount
var QEaccount = new QueryExpression("account");
// Add columns to QEaccount.ColumnSet
QEaccount.ColumnSet.AddColumns("name", "ah_account_type", "accountid", "address1_country");
// Define filter QEaccount.Criteria
QEaccount.Criteria.AddCondition("address1_country", ConditionOperator.Equal, QEaccount_address1_country);
I have an issue with next scheme, I attached it.I want to query from my database with only one object with "Manufacturer" class. Like:
var res = new XPQuery<Manufacturer>(session);
And then query all info that are related to my condition in LINQ.
I have tried XPLiteObject, XPObject, Association attribute, NoForeignKey Attribute, XPOCollection and a lot of stuff but nothing didn't help me.
I have tried a lot of approaches and every time I have new exception like:
SelectMany - method is not supported.
Can't set foreign key in table.
Duplicate primary key.
My question is: how to describe classes for normal extraction data from db?
UPD:
My solution now is: to use .ToList() at every object
and then use linq-query for join data and make needed query.
var manufacturer = new XPQuery<Manufacturer>(session).ToList();
var cars = new XPQuery<Car>(session).ToList();
var countries = new XPQuery<Country>(session).ToList();
var result = from m in manufacturer ....
So, I have found a solution to my question.
I downloaded DevExpress that can add templates for visual studio.
Then I select Add new item to my project named "DevExpress ORM DataModel Wizard".
This wizard can create persistent objects for existing database.
After that I can query database with next syntax:
var manufacturer = new XPQuery<Manufacturer>(session).Select(x => x....)...;
But if you want to use .SelectMany() in your LINQ query you should use .ToList() and then use .SelectMany(). I faced with a lot of issues when I have tried to join or perform some other LINQ related operations. Well, if you got some errors, firstly after .Select() try .ToList() and then perform your operation.
I have a DataGridView that I want to bind to a LINQ query where it will update the database.
First I had something like this
//Select the values I want which include using a Navigation Property
var query = from c in _data.OrdersTables
where c.FamilyID == _familyID
select new { c.ItemInfo.ItemName, c.Requested, c.Paid };
var results = query.ToList();
dataGridViewOrderInfo.DataSource = results;
This works fine for displaying data but when you use select new it kills the connection to the database and you have to use the new statement to select specific columns.
Now I have this
var query = from c in _data.OrdersTables
where c.FamilyID == _familyID
select c;
var results = query.ToList();
dataGridViewOrderInfo.DataSource = results;
I just pull the entire row in and then hide the columns I don't want and this works for displaying and editing the values, but only the ones that are in the OrdersTables. I can't use the navigation property to join to another table and display data from it.
I have tried just editing the row header but it won't let me and I also have tried adding a new column but again won't let me. I imagine because the grid is already bound. Extra info the db specified is a sql ce. So I just need a way to bind the datagrid to a custom select statement that might pull from multiple tables. I thought I could maybe make some sort of a view in my .edmx file but I couldn't see a way to do that. I also thought I could just make a database view but I don't think I can with SQL CE.
If you want to hide cloumn,set datagridview.
I have Sql table that contains two fields Title and Description, I use LINQ to SQL for all datbase operations, how would I get similar items depending on the item that I am currently showing to the user, I know this can be done by using Full Text Search in SQL but LINQ to SQL doesn't support it.
Can someone explain me logic beheind this, or show me example how it's done? Should I split Title and Description on words and then search the table or? SO similar questions system seems perfect, how do they do it?
There is a function called Contains() , I think It will solve your problem , here is an example about how to use It :
db = new YourDataContext();
List<Table> list = new List<Table>();
list = (from i in db.Table where (i.Item.Contains(curentItem)))select i).ToList();
Let's say I have two tables:
Report
Comment
And assuming I have a database context:
var reports = db.Reports();
How can I make sure all Comments for each report are loaded as well?
At this point I want to disconnect from the database but still
have access to the comments. (For example:)
reports[0].Comments[0].Subject
I'm assuming that there is an 1-M FK relationship between reports and comments (1 Report can have many Comments)?
One option is to use the DataLoadOptions.LoadWith method - something like the following:
var reports = db.Reports();
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Reports>(r => r.Comments); // Ask for Comments along with reports
reports.LoadOptions = dlo;
Now, every time you select a report on that data context, the comments will be fetched from the db along with it.
Just beware that ALL fields from comments will be selected - there is no way using this method to select a subset of fields.
Another option is to be specific about what you want to select in the Linq query, e.g.
var myReportsList = from report in db.Reports
select new { // Using anonymous type, but could use a custom class
Report = report,
Comment = report.Comment.Detail, // for example
Subject = report.Comment.Subject
};
To understand when the query gets run and the database connection closed, you will need to understand:
The deferred execution model of Linq and Linq To Sql (Basically, for Linq to SQL, the query only runs when the results are asked for e.g. by iterating over the collection or binding to a grid)
The difference between IQueryable and IEnumerable
Jon Skeets "C# in depth" gives a great overview of these, and i've also heard very good things about "Linq in Action" - plus there are plenty of blog posts about these concepts which do the subjects more justice than I can do here ;o)
Keep in mind that if you use LoadOptions to define a multi-hop path (Reports, comments, anotherentity), the 3rd and further hops are loaded (if related over 1:n relationships) by code which is very inefficient: they'll execute one query per parent. For reports-comments, it's ok, they'll be fetched in 2 queries.