What is the difference between Query and Invoke in ria services? - wcf-ria-services

What is the exact difference between [Query] and [Invoke] in Ria services?

You add methods to a domain service that perform the data operation you want to expose. For example, you can add methods that perform the following operations:
Query
Update
Insert
Delete
Query methods return either a single Entity object, an IQueryable object, or an IEnumerable object.
In addition, you can add the following more complicated operations:
Invoke – operations that need to be executed without tracking or deferred execution. Used only with non-entity data, and used only when query, update, insert, or delete operations cannot be used instead.
Named Update – custom operations that do not fall into simple modification operations
Invoke operations provide an out-of-band mechanism for returning non-entity data and executing operations with side-effects. For more information about side-effects, see the HasSideEffects property. Invoke operations are usually not appropriate for query methods. Even when an invoke operation returns an entity, the entity is generated for the client project only if it is returned by a query method.
This was gathered from here.
Hope this helps.

Related

Possible to call a stored procedure on a Table-Per-Hierarchy table in EF Core 3.1?

I'm moving from EF Core 2.2 to 3.1. One breaking change (#15392) was that it no longer composed over stored procedures, so you had to add 'AsEnumerable'. That usually works, but I have a stored procedure call on a TPH table where that fails:
My call to the SPROC is:
SqlParameter authorizedUserID_p =
new SqlParameter("#authorizedUserID", authorizedUser.ID);
IEnumerable<Post> query =
context.Posts.FromSqlRaw<Post>("Post.USP_ReadPost #ID, #AuthorizedUserID",
parameters: new[]{ parentID_p, authorizedUserID_p }
).AsEnumerable<Post>();
Post targetPost = query.ToList<Post>().FirstOrDefault<Post>();
And it produces this error, recommending using AsEnumberable (which I'm already using above):
System.InvalidOperationException: FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it.
Consider calling AsEnumerable after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client side.
I believe the reason is because my Posts table is Table-per-hiearchy, as other calls to SPROCS in the same application are working fine. Would appreciate any help possible!
This is yet another issue introduced by EFC 3, tracked by #18232: Impossible to use stored procedures related to entities that inherits another one.
The reason is that SP calls are not composable, and EF Core always try to compose SQL for TPH base entities in order to add discriminator condition. Similar to Global Query Filters, but there you can at least use IgnoreQueryFilters, while here you have no option.
The good news is that it's already fixed in EFC repository. The bad news is that it won't be released until EFC 5.0.
Since AsEnumerable() doesn't help, all you can do is to wait for EFC 5.0. Or, if possible, convert SPs like this to TVF (table valued functions) which are composable. In general, use scalar functions or stored procedures with output parameter(s) for non query returning calls (to be executed with ExecuteSql*), and table valued functions for single query returning calls (to be used with FromSql*). Note that currently EFC does not support multiple query returning stored procedures anyway.

Calling functions in a LINQ query

My question is that how to call a function in LINQ query? e.g
source.Where(x=> double.Parse(x.Col1)==3)
or
source.Where(x=> AnyUserFunction(x.Col1)==true)
Basically my requirement is to check weather Col1 is a numeric value or not, but I occasionally need to call my User Defined functions as well.
The problem is that your Linq to Entities provider doesn't know how to translate your custom methods to SQL. The solution proposed by #teovankot is the easy way to solve this problem, but if you want to work with Linq to Objects I suggest you use AsEnumerable extension method instead ToList because AsEnumerable does not execute the query until you consult the data, it preserves deferred execution, but be careful, try to don't use AsEnumerable or ToList on the entire DbSet because you'd retrieve all rows of that table affecting your application's performance.
Now if you only want to check weather Col1 is a numeric value or not, another solution could be using SqlFunctions.IsNumeric method which is translated into native SQL:
using System.Data.Entity.SqlServer;
//...
source.Where(x=> SqlFunctions.IsNumeric(x.Col1)==1);
You can find another set of functions you can also call in the DbFunctions static class.SqlFunctions are SQL Server specific, whereas DbFunctions aren't.
You can't call user defined functions easy in linq to sql.
But you can do it after you get all your data from DB to your server. Like this:
source.ToList().Where(x=> AnyUserFunction(x.Col1)==true)
Note ToList() call. this will get all your data from DB so you basically working with linq to objects where you can easy use your user defined fucntions.

When is IEnumerable preferred over IQueryable in Entity Framework?

I understand how IEnumerable and IQueryable works. I just cannot imagine a situation where IEnumerable would be needed in entity framework when working with SQL database. I wonder if I can just discard IEnumerable in EF. Can you provide any useful example that shows IEnumerable could be more useful than IQueryable?
There are three situations that come to mind.
When EF cannot convert your query into a correct SQL statement - so you need to bring the results into memory to complete the computation.
When you need to perform operations that involve operators that do not convert to SQL.
When SQL server is slower at producing the computation than an in-memory calculation. Many times I have found that pulling all the data into memory is quicker than letting SQL to do it.
Provided a data source (as IQueryable) can be queried, then yes, use IQueryable - though you shouldn't be creating IQueryable instances or implementing it yourself, that's what EF is for. You will still need to use IEnumerable as method parameters or return types if you're using EF with external data-sources or other data that isn't queryable itself, such as JOINing an EF table with non-EF data.
For example, you'd have a return type as IEnumerable<T> if the data you're returning isn't queryable because you called AsEnumerable or ToList but you don't want to reveal implementation details - but I'd then prefer IReadOnlyList<T> in that case.

Is there query equivalent for EntityManager.getReference()?

In JPA there is a method EntityManager.getReference() that doesn't actually load anything from database but returns a proxy (see e.g.: this thread ) that will be loaded up only when necessary.
What if I would like to have a query that returns list of references instead of loading real objects from database? Is there equivalent for queries?
Use of proxies with getReference is provider specific, so your provider may have options for regular queries and even querying only in memory. Marking basic relationships as lazy, coupled with JPA 2.1's EntityGraph can allow your queries to only return exactly the data you need and leave the rest unfetched.

How to get a detached object from JPA

In my application I need most objects fetched in detached mode (fetched with the find API).
I'm wondering if there is a way to ask a detached object from the JPA provider and save the extra call to detach() API.
In additional I would expect the object created in such mode to be less expensive since the JPA provider doesn't need to add it to the entity manager context.
Is there a way to achieve this with JPA APIs?
Is there a way to achieve such functionality with query results?
Specifically I'm using Eclipse Link so if there is a specific way to do it with this implementation it will be helpful as well.
You can fetch a detached entity without an extra call to detach() if you fetch it outside a transaction. If you are not using container-managed transactions, it's trivial, simply do not start a transaction.
If you are using CMT, you have to make sure the requesting object is not a transaction-enabled EJB:
if in an EJB, suspend the transaction by annotating the appropriate method with:#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED),
or
call the EntityManager from a POJO. You dont have to call it directly, it only impotrant that the query result will end in a non-EJB object.
AFAIK, there is no performance gain to be expected, since the query result will always be put in the current persistence context, however shortlived it may be.
EDIT: There is another possibility to get detached objects which does not depend on transaction demarcations: JPA constructor expressions:
List<DTO> dtos = em.createQuery("SELECT NEW com.example.DTO( o.title, o.version) FROM Entity o").getResultList();
The constructed type must have a constructor with all the relevant attributes. The objects in the list, entities or not, will always be created detached. However there is a small overhead of instantiating a new object.