Call function in query in Entity framework 3.5 - entity-framework

I am trying to run following query in entity framework 3.5
var test = from e in customers where IsValid(e) select e;
Here IsValid function takes current customer and validate against some conditions and returns false or true. But when I am trying to run the query it is giving error "LINQ Method cannot be translated into a store expression." Can any body tell me any other approach?
One approach I can think of is to write all validation conditions here, but that will make the code difficult to read.
Thanks
Ashwani

As the error text implies, the EF Linq provider can not translate the IsValid method into SQL.
If you want the query to execcute in the DB, then you would have to write your validation conditions in the linq statement.
Or if you simply want to fetch all customers and then check if they are valid you could do:
var test = from e in customers.ToList() //execute the query directly w/o conditions
where IsValid(e)
select(e);

Related

How can I use postgresql reverse function with EFCore

I want to create an SQL query with EFCore like below.
FROM "Customers" AS c
where reverse("Phone") LIKE reverse('%#####');
ORDER BY 1
LIMIT #__p_2 OFFSET #__p_1
I'm trying do with LINQ but this code is not working and also I couldn't find reverse method inside EF.Functions
query = query.Where(c => c.Phone.Reverse().ToString() == $"{phone}%");
throws an error
Message": "The LINQ expression 'DbSet\r\n .Where(c
=> c.Phone\r\n .Reverse().ToString() == __Format_0)' could not be translated. Either rewrite the query in a form that can be
translated, or switch to client evaluation explicitly by inserting a
call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for
more information.
Is there any way to create reverse function query with PostgreSQL/Npgsql provider for Entity Framework Core.
Unfortunately there's no simple/idiomatic way to express string reversal in .NET; note that c.Phone.Reverse().ToString() does not return the reversed phone, since it invokes ToString on the IEnumerable returned from Reverse.
I've added EF.Functions.Reverse for the upcoming version 5.0 - see https://github.com/npgsql/efcore.pg/pull/1496.

linQ to entities does not recognize the method Models.Repository.Student get_Item(Int32)' method

getting this error on where clause.
trying to fetch records from sql server with linQ query in entity framework.
var Stud = contextSchool.Student.Where(x => x.STDNT_ID == lstStudent[i].StudentID).FirstOrDefault();
if i store value of list in a variable and then use in where clause, it works but not with list.
complete error:
linQ to entities does not recognize the method Models.Repository.Student get_Item(Int32)' method, and this method cannot be translated into a store expression.
i also get this error on some other projects, the problem is that u cant use methods like get_Item or f.e. AddDays() in ur linq command.
So u kinda have to play around it.
U have to create an object (list, or whatever) before ur linq command and fill it with the data u need (per methods) and use the variable in ur linq command.

How can I get the SqlDbType or DbType from IModel in EntityFramework Core 2?

My use case is:
I have a graph of objects from many entities in Entity Framework Core 2 (EFC 2). In EFC 2, the SaveChanges Operation is very slow. The reason appears to be the limit in number of parameters that Sql Server can receieve per query. As Sql Server receive 2100 parameters per query, saving hundreds of thousands of registers must cause many roundtrips, with much latency implied. See issue 2484 for more information. My current solution is to generate a SqlCommand with a query with Table Valued Parameters (TVP). The plan is to use only one query with a TVP for each table and operation (insert, update and delete), using only one roundtrip for save all the changes. EFC cannot do that actually.
In theory, i'm almost finish this, but i have a problem. To use TVP, i must get the SqlDbType for each column from my Table Type. The Table Types are generated using the metadata in the IModel from EFC. But, i cant get the SqlDbType. Simplified, I tried with:
var typeMapper = new SqlServerTypeMapper(new RelationalTypeMapperDependencies());
var entityType = context.Model.GetEntityTypes().First();
var prop = entityType.GetProperties().First();
var mapping = typeMapper.GetMapping(prop);
var dbType = mapping.DbType;
Having dbType, the plan is get the SqlDbType from dbType using a Dictionary. The problem is dbType is getting null.
I'm searched in the api, and i can get the way to extract a SqlType from IModel. Is this possible?

Dynamic EF Query

I am thinking of designing a business rule engine which basically generates an EF query from a set of string values stored in a database.
For e.g. I will store the connection string, table name, the where condition predicate, and select predicate as string fields in a db and would like to construct the EF query dynamically. For e.g.
var db = new DbContext(“connectionstring”);
var wherePredicate = Expression.FromString(“p => p.StartDate > new DateTime(2014,5,1))
var selectPredicate = Expression.FromString(“p => p”)
var results = db.Set(“Projects”).Where(wherepredicate).Select(selectPredicate)
For constructing the predicates I can use DynamicExpression or Dynamic LINQ library.
However how do I access db.Set(“Projects”) where Projects is the entity name and apply the where and select predicates? (or something like db[“Projects”].Where().Select).
I tried the non-generic version of the DbContext.Set(Type entityttype) method, however couldn’t figure out how to apply Where and Select predicates to the returned object.
I am trying to avoid generating SQL queries and instead rely on dynamically generated EF code.
This doesn't make much sense. You can create method that will work on string instead of generic type using reflection, but you'd have to return DbSet not DBSet<T>. And on that one you cannot execute LINQ's methods (basically), because there's no type (during compilation). Of course you can do it all the way using reflection, but then, why??? You're loosing 90% of what O/R mapper does for you.

Convert String to Int in LINQ to Entities

I am trying to duplicate the following SQL statement as a LINQ to Entities query (where "PRODUCTS" is the table mapped to the entity) ... NOTE IQueryable ... most of what I have seen posted as solutions convert either the search parameters, or the dump the results into an IEnumerable and then proceed to convert from there. I am dealing with 100's of millions of records and cannot afford to load 200 million records into memory, only to have to filter through them again. I would like, if possible to do this in a single query to the databse.
select *
from PRODUCTS
where
MODEL_CODE = '65' and
CAST(SERIAL_NUMBER as int) > 927000 and
CAST(SERIAL_NUMBER as int) < 928000
I have tried the following ...
int startSN, endSN;
startSN = 9500
endSN = 9500
if (!int.TryParse(startSerialNumber, out startSN))
throw new InvalidCastException("The start serial number was not a valid value");
if (!int.TryParse(endSerialNumber, out endSN))
throw new InvalidCastException("The end serial number was not a valid value");
IQueryable<PRODUCT> resultList = base.Context.PRODUCTS.Where(b =>
(Convert.ToInt32(b.SERIAL_NUMBER) > startSN) &&
(Convert.ToInt32(b.SERIAL_NUMBER) < endSN)).AsQueryable();
I have tried a couple of other version of things similiar to this with no luck. I have looked at the following posts also with no luck.
Convert string to int in an Entity Framework linq query and handling the parsing exception - the solution converts query to a list before converting the entity properties.
Convert string to Int in LINQ to Entities ? -
This problem was just with converting the parameters which can be easily done outside the LINQ to Entities statement. I am already doing this for the parameters.
LINQ to Entities StringConvert(double)' cannot be translated to convert int to string - This problem is actually the reverse of mine, trying to convert an int to a string. 1) SqlFunctions does not provide a function for converting TO an int. 2) Ultimately the solution is to, again convert to an IEnumerable before converting/casting the values.
Anybody got any other ideas? I am little stumped on this one!
Thank you,
G
If you don't use code-first, but an EDMX based approach model defined functions are probably the best solution: Convert String to Int in EF 4.0
Alternatively you can use...
base.Context.PRODUCTS.SqlQuery(string sql, params object[] parameters)
...and then pass in the raw SQL statement from your question.
DbSet<T>.SqlQuery(...) returns a DbSqlQuery<T> as result. It is important to keep in mind that this type does not implement IQueryable<T>, but only IEnumerable<T>. Its signature is:
public class DbSqlQuery<TEntity> : IEnumerable<TEntity>, IEnumerable, IListSource
where TEntity : class
So you can extend this result with further LINQ methods, but it is only LINQ to Objects that will be executed in memory with the returned result set from the SQL query. You can not extend it with LINQ to Entities that would be executed in the database. Hence, adding .Where filters to DbSqlQuery<T> does not have any influence on the database query and the set of data that is loaded from the DB into memory.
That's actually not surprising as it would mean otherwise that a partial expression tree (from a Where method) had to be translated into SQL and then merged into a hand-written SQL statement so that a correct new composed SQL statement results and could be sent to the database. Sounds like a pretty hard task to me.