ESQL in Entity Framework - entity-framework

Is there any good and, if possible, exhaustive documentation about ESQL in entity framework ?
I'm trying to make a select of an entity object with modification of a property using a method; something like this :
SELECT foo FROM context.foo WHERE foo.Price = AddTaxes(foo.Price)

There is msdn providing some documentation Entity SQL Language
You can also combine it with Linq2Entities with something like
context.foo
.Where("it.Price == #Price", new ObjectParameter[]
{ new ObjectParameter("Price", AddTaxes(price) } ).ToList()

Related

How to call builtin SQL Linq functions in EF Core?

I have a query written with Linq and EF Core 6 and I would like to call the builtin function EOMONTH on a date column.
Something like:
_context.Pet
.Select(x => EOMONTH(x.birthDate))
.DoStuff()
.ToListAsync();
How can I actually get to call EOMONTH and any other builtin SQL function from Linq?
The EF Core documentation has a page that show function mappings between LINQ and SQL.
As of EF Core 6, it looks like EOMONTH isn't yet supported, but you can provide your own function mapping like this:
class MyContext : DbContext
{
[DbFunction(IsBuiltIn = true)]
public static DateTime EOMONTH(DateTime startDate)
=> throw new InvalidOperationException(
"Don't call EOMONTH directly. It must to be translated to SQL " +
"inside of a LINQ query.");
}
_context.Pet
.Select(x => MyContext.EOMONTH(x.birthDate));
Note, lots of different styles are supported by EF. For example, it could also be an instance method. Read the docs to find the best way that works for you.

Where does a custom sql statement go in a code first entity framework project

Where does a custom sql statement go in a code first entity framework project?
using (var context = new BloggingContext())
{
var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList();
}
It doesn't feel right placing it in a controller. So maybe in the IdentityModel.cs class?
One of the strong positives of entity framework is that you seldom need to use SQL strings anymore. The disadvantage of the strings is that they can't be checked by the compiler and thus are error prone, especially after changing the database.
If you'd designed your classes according to the Entity Framework Code First conventions your statement would be like:
using (var dbContext = new BloggingContext)
{
// get all Blogs (note: very unusual!)
var blogs = dbContext.Blogs.ToList();
}
Sometimes you need to explicitly use a SQL statement, for instance when calling a stored procedure. you could use object DbContext.Database:
using (var dbContext = new BloggingContext)
{
string sqlCommand = ...
Database database = dbContext.Database;
database.ExecuteSqlCommand(sqlCommand, <parameters>);
}
Database.ExecuteSqlCommand uses the traditional method of querying databases.

Entity Framework 6: .Where and .Select that accept string parameters?

In “Programming Entity Framework”, 2nd edition by Julia Lerman, in chapter dedicated to Entity SQL, p. 115, we have the following example of using query builder method to do projection using EF 4.1 .Where and .Select with string parameters:
ObjectQuery<DbDataRecord> contacts = context.Contacts
.Where("it.FirstName='Robert'")
.Select("it.Title, it.FirstName, it.LastName");
I am using Entity Framework 6, .Net 4.6, VS 2015. The compiler complains that there are no .Where and .Select that accept string parameters, only lambdas. Is there any solution how to follow this book example?
The example appears to be about the old ObjectQuery API, which shouldn't really be used now. It's still possible to use it with EF6.x though, with something like the following:
ObjectContext objectContext = ((IObjectContextAdapter)conte).ObjectContext;
ObjectSet<DbDataRecord> objectSet = objectContext.CreateObjectSet<DbDataRecord>("DbDataRecords");
// Async version: var res0 = await objectSet.Where("it.FirstName='Robert'").ToListAsync();
var res0 = objectSet.Where("it.FirstName='Robert'").ToList();
That said, you really should use the lambda instead with the new DbContext API.

Using CreateSourceQuery in LINQPad

How can I get linqpad to understand CreateSourceQuery in the following C# statements?
var airline = Airlines.FirstOrDefault(a => a.ID == 1776);
airline.Dump();
var crew = airline.Crew.CreateSourceQuery().Where(c => c.Title == "pilot");
crew.Dump();
Where Airlines.Crew is a navigation property. Linqpad gives the error:
'System.Data.Linq.EntitySet' does not contain a
definition for 'CreateSourceQuery' and no extension method
'CreateSourceQuery' accepting a first argument of type
'System.Data.Linq.EntitySet' could be found
Is this perhaps just a reference I need?
CreateSourceQuery is an Entity Framework method. LINQPad uses LINQ-2-SQL by default.
There's a walk-through on the LINQPad website which explains how to use it with Entity Framework:
http://www.linqpad.net/EntityFramework.aspx

how to prevent EF from trying to map a method on my model?

So, I've got a "Speaker" class, with normal properties, and a plain old method like this:
public string FullNameFirstLast()
{
return FirstName + " " + LastName;
}
I'm using Entity Framework Code First Magic Unicorn edition, and I get this error:
System.NotSupportedException: LINQ to
Entities does not recognize the method
'System.String FullNameFirstLast()'
method, and this method cannot be
translated into a store expression.
Which seems odd, since it is a method and not a property, so I wonder why EF would care about it anyway... So I tried telling EF to ignore it like so:
modelBuilder.Entity<Speaker>()
.Ignore(ignore => ignore.FullNameFirstLast())
;
Which doesn't help, because now I get this error message instead:
System.InvalidOperationException: The
expression 'ignore =>
ignore.FullNameFirstLast()' is not a
valid property expression. The
expression should represent a
property: C#: 't => t.MyProperty'
VB.Net: 'Function(t) t.MyProperty'.
How do I do this? I'm assuming that I can have methods on my model objects with EF, right??
It is not a problem of mapping. It is problem of using the method in Linq-to-entities query. You can't use custom methods or custom properties in Linq-to-entities query because EF provider doesn't know how to translate them to SQL.