is there an possibility to call the Math.Sin()-function in a Linq To Entites (Entity Framework 4) -Query?
I've read, that the current Entity Framework 4 doesn't implement this function.
Maybe there's a workaround to this solve problem?
(I don't want to invite all entries in the memory.)
Thanks and best regards
Several functions that (usually) have obvious SQL counterparts, like Math.Sin can't be used directly in Entity Framework queries. Presumably this is because they can't be reliably translated to different SQL implementations. A ton of MSSQL-specific functions are, however, exposed as static methods in the class System.Data.Objects.SqlClient.SqlFunctions. They throw exceptions if you call them directly, but are translated into the proper SQL if used in a LINQ query.
See this blog post about the magic that's happening under the covers (namely the EdmFunction attribute).
It is certainly possible to use such function starting with EF4. In EF4, EF team introduced SqlServer functions that can be consumed in linq. You should alway consider using canonical functions cuz they are database agnostic and every vendor should convert those functions to store specific equivalent. However when such functions are not available, you can resort to SqlServer namespace (ESQL) or SqlFunctions for linq
from l in db.Locations
select SqlServer.Sin(l.Latitude) + SqlServer.power(l.Longitutde)
I cover several of these options in my functions chapter in my book. Specifically you can look at 11-10 recipe Calling database function in esql
11-11 Calling Database Function in LINQ
Unfortunately it's impossible to call Math.Sin in a LinqToEntities query (or Entity SQL query).
The only way to accomplish this without resorting to retrieving all objects first, is to write a SQL query that does what you want and call it via ObjectContext.ExecuteStoreQuery. This isn't as bad as it sounds because you can still get back typed results.
EDIT: After reading the other answers, it appears that it is possible to call these types of functions (SqlFunctions contains 44 functions with various overloads). I leave my original answer as is because it's another way of achieving the same result.
Related
I found some lines of code online and I understand the first two lines. Data of a particular
type is cached and stored in the two properties of the models below.
model.payment = (List<CompInfor>)HttpRuntime.Cache[cacheKey + "_received"];
model.FilteredPayment = (List<CompInfor>)HttpRuntime.Cache[cacheKey + "_received"];
However I don't understand the line below as I have never written code like this below.
Please what does this line do? What does it mean? I know you can save a lot of resources by using IQueryable.
IQueryable<CompInfor> payment = model.FilteredPayment.AsQueryable<CompInfor>();
It simply returns an instance of the IQueryable<T> interface which will utilize a query provider to act upon the object in question (in your case, the model.FilteredPayment list). It doesn't seem to make much sense when you're acting against a List locally, but (as an example) in the case of entity framework where you build query statement to be executed against a database via SQL, the Linq to Entities query provider processes the IQueryable into the appropriate SQL statement for execution against the database and processes the results.
i am new in MVC and entity frame work and i want to create Code first entity frame work.
we have already created project in asp.net and we want to migrate in mvc. we have lots of stored procedure and some procedure return complex data combination of 10 to 12 tables...
As a Proof of Concept we wan't to develop 3 to 4 pages...
i have some question regarding new start.
1) Should i used entity frame work if yes then which is better entity frame work model
Database first
Model first
code first
2) how to integrate stored procedure in Code first model
3) in each page we have minimum 7 to 8 table result there... how i will handle in entity frame work.
this is my first project in mvc and entity framework please help me with appropriated answer.
first, this has nothing to do with MVC. this is purely a data access issue.
second, this is sort of missing the point of using entity framework. if the goal is to migrate away from stored procs that one thing, but to use EF and continue to execute the stored procs defeats the purpose of using a ORM like EF.
Instead for your procs I would stick with raw ADO.Net, or use Dapper.Net to convert the stored proc result sets into objects.
EF would be a better choice as your convert each proc into EF linq queries. It's not that you can't execute procs (or raw sql) from EF, but it doesn't make much sense. Especially with how you describe the procs.
I've seen other questions regarding using straight SQL for MVC data access, for example here. Most responses don't answer the question but ask
"Why would you not want to use ORM, EF, Linq, etc?"
My group does custom reporting out of a data warehouse that requires a lot of complex, highly tuned Oracle queries that are manipulated based on user GUI parameter selections.
My newest project is to develop a SQL plugin reporting tool for SQL report developers. They would create a pre-tuned SQL for the report with pseudo parameters and enter (and store) via the GUI. Then the GUI would prompt them for the parameter definitions (name and type) that need to be displayed/requested at run time to ultimately replace the pseudo variables.
So a SQL statement may look like:
SELECT * FROM orders WHERE order date BETWEEN '<Date1>' AND '<Date2>'
And the report developer would then, via the GUI, add two parameters named Date1 and Date2, and flag them as date fields.
End users would then select the report, get prompted for Date1 and Date2, and the GUI would do the substitution and run the SQL.
As you can see, I have no choice but to use straight SQL (especially in the 2nd example and understand I would have to forgo strongly typed in the 2nd also).
So my questions are:
When is it necessary to bypass EF/Linq (and there are definitely reasons to), what is best practice in MVC 4?
And how best to strongly type when I do know the output columns ahead of time?
And CRUD processing?
Can anyone point me to any examples of non-EF/Linq based coding in this regard?
I think this is a bit open ended question, so here's my 2c. (If tl dr, go to last section)
To me, it's not so much "by passing EF/Linq", but rather, the need to choose the appropriate data persistence library. I have used PetaPoco, Ado.Net, NHibernate/ActiveRecord, Linq2Sql, EF (My main choice) with MVC.
Best practice actually comes from realising that Controllers are STILL a part of presentation layer, and that it should not deal with anything other than HttpContext related operations + calling business logic service classes.
I arrange my classes as:
Presentation (MVC) -> Logic Services (Simple classes) -> Data Access (Context wrapped in "repositories").
So I can't quite imagine whether to use EF or not would have any implication on asp.net MVC.
For me, Data Access returns data in DTO, e.g.
public List GetAllFoos()
Whether that method string concatenate from a xml, etc or do a simple Context.Foos.ToList() is irrelevant to the rest of the application. All I care is Data Access do NOT return me a DataSet with string matching for columns. Those stay in DAL.
See point 1 and 2. My repositories have CRUD methods on it. How it's done is irrelevant to the rest of application. Take one of the most basic interface to my repositories classes:
public interface IFooRepository
{
void Save(Foo foo)
Foo Get(int id)
void Create(Foo foo)
void Delete(int id)
}
One point not mentioned yet, DI is also crucial. The concrete implimentation "FooRepository" may choose to request dependencies such as Web services, context classes, etc. Those are, however, again, completely irrelevant to the caller who depends on the interface.
If you still require an example after the 3 points above, drop a comment and I'll whip up something extremely simple using Ado.net.
===========================================================================
To EF or not to EF.
For me, if starting a new project with new schema, I use EF code first.
Fitting new code to old database + old project has no ORM mapping I can reuse = PetaPoco.
===========================================================================
In the context of your project:
The "SQL plugin reporting tool for SQL report developers". "The" sql reporting service? I'm not sure why you need to do anything? Doesn't SSRS already do that? (Enter sql statement/data source, generate form for parameter, etc).
If not I'd question the design decision. IMVHO, the need for users of an application (I don't care if it's "report developer" or w/e) to enter SQL statements is usually stemmed from "architectural astronauts". How do you debug the SQL statement when you enter via GUI as a string? How do you know the tables and the relationships? You either dig into SSMS and come back to gui, or you build complex UI (aka rebuild SSMS).
At the end of day, if you want bazillion reports for gazillion different users, you have to pay for it. I see too many "architectural astronauts" who exposes application to accept SQL statements only to make everyone waste time guessing what should be put into it. No cost saving at all.
Ok, if you must do that, well eh... Good luck. Best bet is to return as a DataTable and dump the rows/columns/data on to the view with nested foreach looping through rows then columns.
I'm using Entity Framework 5, and I reverse engineer code first the database I'm using, and then I added an ADO.NET Entity Data Model so that I can use Stored Procedures as reverse engineer code first didn't provide the use of sprocs. Is this the only way to access sprocs?
Also, I realize that after the reverse engineer code first process is done a bunch of classes (tables from the database) are created but as soon as I add the ADO.NET Entity Data Model, most of the classes go away. Does anybody know why?
DbContext.Database property exposes useful methods
http://msdn.microsoft.com/en-us/library/system.data.entity.database(v=vs.103).aspx
ExecuteSqlCommand( string, object[] )
http://msdn.microsoft.com/en-us/library/system.data.entity.database.executesqlcommand(v=vs.103).aspx
SqlQuery<TEntity>( string, object[] )
http://msdn.microsoft.com/en-us/library/gg696545(v=vs.103).aspx
There is a pattern that you can follow to create or support store procedures with the code first approach. here is a link that you can use to follow this:
http://www.codeproject.com/Articles/179481/Code-First-Stored-Procedures
In few words you need to do the same that you do with model first, create a class that supports the inputs and a class that supports the result set.
And about the Data Entity Model and missing classes. You need to consider that you only can have one approach in a project: code first/(model first/database first), so this could be the reason why you are not seeing those clases.
You can use Context.Database.SqlQuery to run SP.
I started working with linq to SQL several weeks ago. I got really tired of working with SQL server directly through the SQL queries (sqldatareader, sqlcommand and all this good stuff).
After hearing about linq to SQL and mvc I quickly moved all my projects to these technologies. I expected linq to SQL work slower but it suprisongly turned out to be pretty fast, primarily because I always forgot to close my connections when using datareaders. Now I don't have to worry about it.
But there's one problem that really bothers me. There's one page that's requested thousands of times a day. The system gets data in the beginning, works with it and updates it. Primarily the updates are ++ # -- (increase and decrease values). I used to do it like this
UPDATE table SET value=value+1 WHERE ID=#I'd
It worked with no problems obviously. But with linq to SQL the data is taken in the beginning, moved to the class, changed and then saved.
Stats.registeredusers++;
Db.submitchanges();
Let's say there were 100 000 users. Linq will say "let it be 100 001" instead of "let it be increased by 1".
But if there value of users has already been increased (that happens in my site all the time) then linq will be like oops, this value is already 100 001. Whatever I'll throw an exception"
You can change this behavior so that it won't throw an exception but it still will not set the value to 100 002.
Like I said, it happened with me all the time. The stas value was increased twice a second on average. I simply had to rewrite this chunk of code with classic ado net.
So my question is how can you solve the problem with linq
For these types of "write-only queries" I usually use a Stored Procedure. You can drag the stored procedure into the designer and execute it through the Linq to SQL DataContext class (it will be added as a method).
Sorry for the trite answer but it really is that simple; no need to to finagle with raw ADO.NET SqlCommand objects and the like, just import the SP and you're done. Or, if you want to go really ad-hoc, use the ExecuteCommand method, as in:
context.ExecuteCommand("UPDATE table SET value = value + 1 WHERE ID = {0}", id);
(But don't overuse this, it can get difficult to maintain since the logic is no longer contained in your DataContext instance. And before anybody jumps on this claiming it to be a SQL injection vulnerability, please note that ExecuteCommand/ExecuteQuery are smart methods that turn this into a parameterized statement/query.)
Linq to Sql supports "optimistic" concurrency out of the box. If you need tighter control, you can add a Timestamp column to your table, and Linq to Sql will use that timestamp to tighten the concurrency.
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/01/10557.aspx
However, as Morten points out in the comments below, this solution is not going to perform well. Of course, you can always use ADO.NET to update the value, just like you were doing before; that won't adversely affect the operation of your Linq queries at all.
You could turn off concurrency on that property by changing the UpdateCheck value:
http://msdn.microsoft.com/en-us/library/bb399394(v=VS.90).aspx
Messy if your using generated code and the designer but I think this is the only way to do this.