How to use calculated fields in my LightSwitch Query? - linq

in my lightswitch application im trying to create a Customers Screen for customers who have balance value, and my balance value is a Calculated Field in the Customer Entity
when i tried to put the logic in the Process Query Event Like This
query =( from i in query
where(i.Balance>0)
select i );
i get an exception .. what is the best way to handle these kind of situations ??
i saw an answer here but i didn't know how to implement it exactly i need a sample code for it can anyone help me ??
thanks in advance

The query will be executed by the data provider, which doesn't know about calculated fields. What you can do is to filter what you want via LINQ, referring to the actual fields, not the calculated ones.
For example, let's say Balance is your calculated field, that you defined as Credit - Debit (which are normal fields). You want your query to return the rows where Balance > 0. This is how you'd write the query (in the PreprocessQuery event, note there is no ProcessQuery event):
partial void TestQuery_PreprocessQuery(ref IQueryable<Customer> query)
{
query = (
from c in query
where ((c.Credit - c.Debit) > 0)
select c);
}
Another theoretical way of solving the problem would be setting a filter in the Executed event handler. However, for whatever the reason, when I do it, the filter is not applied to the screen. But even if this method would work, still you'd be filtering on the client side, which might not be what you want.

I'm actually looking for a solution to this problem
(unfortunately I can't just include the calculation from the calculated field, because my calculation uses another calculated field which uses recursion)
A couple of pointers I thought you might find helpful:
#julio.g - for the Executed event handler, the "result" parameter is an IEnumerable parameter (as opposed to the PreProcess_Query event handler, where the "query" parameter is a ref IEnumerable) so any changes you make to the "result" will only be local to that method
#3oon - afaik, SQL Views are not supported in LightSwitch. The best option I've come across so far is to create a WCF RIA Service based on a Stored Procedure, then adding it as a datasource.
This blog post should help get you started.
http://tejana.wordpress.com/2010/12/09/microsoft-lightswitch-and-stored-procedures-using-wcf-ria-services/
Hope that helps!

Related

Executing DAX query via .NET Core AdomdConnection returns null

I have a very simple DAX query which I can execute via SSMS with no problems.
As show above, the query returns 2 rows, one from the dynamic expression and one hardcoded "123".
When executed via C# Microsoft.AnalysisServices.AdomdClient, the hardcoded "123" row value is returned (oddly the ordinal position of rows does not match the execution in SSMS), but the dynamic expression row value is always null. This issue does seem to be isolated to the tables of this model as querying brand new "AdventureWorks" model programmatically does return values for dynamic expressions as well.
I am at a loss of what to explore next and I don't have high familiarity with querying Analysis Services programmatically, so any help would or hints what to try would be much appreciated.

Sorting on a calculated field with X++

I am a long time developer in MS Access but Now I need to develop in Microsoft Dynamics AX 2009.
I have a report that uses a method on the body of a report that calculates an "exp book date". Now I am being asked to sort on this field.
I am guessing I need to move the method to the query, in order to make the field able to be sorted.
But when I copy the method to the Method level of the query, it say that the field does not exist. Which it doesn't. How do i get the feild to be visiable?
display utcDatetime Test()
{
real AddDays;
utcDatetime CDate;
;
AddDays = smmQuotationPrognosisGroup::find(smmOpportunityTable_1.PrognosisId, false).PrognosisDays;
CDate = smmOpportunityTable::find(smmOpportunityTable_1.OpportunityId, false).createdDateTime;
return DateTimeUtil::addDays(CDate, AddDays);
}
Unfortunately it is not possible to sort directly by a display method.
Yet there are some workarounds, e.g.:
Use a temporary table with a field which is filled by your display method's logic before you run the report and then use this temporary table in your query.
Override the report's fetch method so that you have full control over
fetching the data via X++.
Depending on your report's size these actions can take some time.

How can I get the IQueryable object used by LinqDataSource?

Is there a way to get the IQueryable object that the LinqDataSource has used to retrieve data? I thought that it might be possible from the selected event, but it doesn't appear to be.
Each row in my table has a category field, and I want to determine how many rows there are per category in the results.
I should also note that I'm using a DataPager, so not all of the rows are being returned. That's why I want to get the IQueryable, so that I can do something like
int count = query.Where(i => i.Category == "Category1").Count();
Use the QueryCreated event. QueryCreatedEventArgs has a Query property that contains the IQueryable.
The event is raised after the original LINQ query is created, and contains the query expression before to it is sent to the database, without the ordering and paging parameters.
There's no "Selected" event in IQueryable. Furthermore, if you're filtering your data on the server, there'd be no way you can access it, even if the API exposed it, but to answer a part of the question, let's say you have category -> product where each category has many products and you want the count of the products in each category. It'd be a simple LINQ query:
var query = GetListOfCategories();
var categoryCount = query.Select(c => c.Products).Count();
Again, depending on the type of object GetListOfCategories return, you might end up having correct value for all the entries, or just the ones that are loaded and are in memory, but that's the different between Linq-to-Objects (in memory) and Linq-to-other data sources (lazy loaded).

Linq equivalent of SQL LEFT function?

We have a database with some fields that are varchar(max) which could contain lots of text however I have a situation where I only want to select the first for example 300 characters from the field for a paginated table of results on a MVC web site for a "preview" of the field.
for a simplified example query where I want to get all locations to display in the table
(this would be paginated, so I don't just get everything - I get maybe 10 results at a time):
return db.locations;
However this gives me a location object with all the fields containing the massive amounts of text which is very time consuming to execute.
So what I resorted to before was using SQL stored procedures with the:
LEFT(field, 300)
to resolve this issue and then in the Linq to SQL .dbml file included the stored procedure to return a "location" object for the result.
However I have many queries and I don't want to have to do this for every query.
This maybe a simple solution, but I am not sure how I can phrase this on a search engine, I would appreciate anyone who can help me with this problem.
You can use functions that directly translate to those functions too, this is useful when you need to translate code that functionally works just fine in SQL at no risk in LINQ.
Have a look at System.Data.Objects.EntityFunctions
Locations.Select(loc=>System.Data.Objects.EntityFunctions.Left(loc.Field,300))
This will get directly translated into a LEFT on the server side.
EDIT: I misread LEFT for LTRIM. Here's all the String functions that can't be used in LINQ to SQL. Have you tried String.Substring()?
Your best option is to map the stored procedure and continue using it. Here is an excellent article with screen shots showing you how to do so.
If you're not using the designer tool you can also call ExecuteCommand against the DataContext. It isn't pretty, but it's what we have for now.
I found something like this worked for me:
return from locationPart in db.locations
select new LocationPart
{
Description = locationPart.description,
Text = locationPart.text.Substring(0,300)
};
Not ideal because I have to use "select new" to return a a different object, but it seems to work.

Linq stored procedure with dynamic results

So I'm extremely new to Linq in .Net 3.5 and have a question. I use to use a custom class that would handle the following results from a store procedure:
Set 1: ID Name Age
Set 2: ID Address City
Set 3: ID Product Price
With my custom class, I would have received back from the database a single DataSet with 3 DataTables inside of it with columns based on what was returned from the DB.
My question is how to I achive this with LINQ? I'm going to need to hit the database 1 time and return multiple sets with different types of data in it.
Also, how would I use LINQ to return a dynamic amount of sets depending on the parameters (could get 1 set back, could get N amount back)?
I've looked at this article, but didn't find anything explaining multiple sets (just a single set that could be dynamic or a single scalar value and a single set).
Any articles/comments will help.
Thanks
I believe this is what you're looking for
Linq to SQL Stored Procedures with Multiple Results - IMultipleResults
I'm not very familiar with LINQ myself but here is MSDN's site on LINQ Samples that might be able to help you out.
EDIT: I apologize, I somehow missed the title where you mentioned you wanted help using LINQ with Stored Procedures, my below answer does not address that at all and unfortunately I haven't had the need to use sprocs with LINQ so I'm unsure if my below answer will help.
LINQ to SQL is able hydrate multiple sets of data into a object graph while hitting the database once. However, I don't think LINQ is going to achieve what you ultimately want -- which as far as I can tell is a completely dynamic set of data that is defined outside of the query itself. Perhaps I am misunderstanding the question, maybe it would help if you provide some sample code that your existing application is using?
Here is a quick example of how I could hydrate a anonymous type with a single database call, maybe it will help:
var query = from p in db.Products
select new
{
Product = p,
NumberOfOrders = p.Orders.Count(),
LastOrderDate = p.Orders.OrderByDescending().Take(1).Select(o => o.OrderDate),
Orders = p.Orders
};

Resources