I'm currently working with ASP.NET Core and I want to use Automapper to map a Linq Expression. The mapping statement is:
var targetConditions = _mapper.Map<Expression<Func<Entity, bool>>>(filter);
where filter is a formal parameter in the form:
(Expression<Func<EntityDTO, bool>> filter
In the mapping profile I have the following map created:
CreateMap<Expression<Func<EntityDTO, bool>>, Expression<Func<Entity, bool>>>();
I'm using a generic repository pattern with EF. I want to get a list of DTOs filtered by, of course, DTO's fields from my controller. I then need to convert from DTO filter to entities filter in the Business Layer before doing any query using Linq for EF.
Even though the expression does get coverted from EntityDTO to Entity, the parameters in the lambda expressions inside don't, raising all sorts of errors when I further use it with EF. Any idea how can this be done?
Try this:
IQueryable<Customer> query = repository.getCustomers(); // entities query
query.ProjectTo<CustomerDto>().Where(dtoFilterExpression)
Related
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.
It is easy to do a Contains, StartsWith, or EndsWith query in Entity Framework when you know the pattern you'd like to find. But how to do the equivalent of "LIKE [Column]"?
For instance, this is easy:
Name LIKE '%Th'
But how do you do this? where Prefix is a column.
Name LIKE [Prefix]
I tried to use the SqlMethods and got the following error.
LINQ to Entities does not recognize the method 'Boolean Like(System.String, System.String)' method, and this method cannot be translated into a store expression.
I resolved this problem by using LINQ to Entities to bring back the set of data that I wanted, then using LINQ to Objects to filter the data.
I do not think there is currently a way to have a LINQ to Entities query be resolved in a database server as ...
... LIKE [column-name]
First, SqlMethods is for use in LINQ-to-SQL, not LINQ-to-Entities.
The best you can do to use the filter in the database engine (so you don't have to pull all data in memory first) is:
context.Entities.SqlQuery("SELECT * FROM EntityTable WHERE Name LIKE Prefix")
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.
How can I achieve following query method in Entity Framework,
below is a snippet from NHibernate documentation http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html
Example example = Example.create(cat)
.excludeZeroes() //exclude zero valued properties
.excludeProperty("color") //exclude the property named "color"
.ignoreCase() //perform case insensitive string comparisons
.enableLike(); //use like for string comparisons
List results = session.createCriteria(Cat.class)
.add(example)
.list();
Entity framework is LINQ based. Linq is said to be a declarative language, which means so much as telling what to do in stead of how to do it (imperative). A statement like
context.Orders.Select(o => o.OrderDate).Distinct();
is a declarative shortcut, if you like, for a 'ceremonial' foreach statement in which OrderDates are added to a list if they were not added to it before.
I'm not an expert in NHibernate or its criteria API, but the criteria API seems to be even more declarative than linq. That makes it hard to compare them. A few differences:
The main one: query by example is not possible in EF.
There is no way in linq to set behaviours for a whole query. For instance, if you want to exclude zero valued properties, you'll have to specify each one of them in a where predicate (which is closer to telling how to filter).
Case sensitivity is downright underdeveloped in EF. For example, a statement like
People.Where(c => string.Compare( c.Name, "z", false) > 0)
will generate the same SQL as
People.Where(c => string.Compare( c.Name, "z", true) > 0)
The database collation determines the case sensitiveness of string comparisons.
You can do LIKE queries, but, again, specified for each individual predicate:
People.Where (c => c.Name.Contains("a"))
(again: no differentiation in case)
So I can't really give a linq translation of your criteria query. I'd have to know the class properties to be able to specify all individual predicates.
In EF 4, the default ObjectSet is available for each entity. For example, I have table Employee, after gererated Entity Model, EF will create ObjectSet on Employee.
Then when using wcf ria service, the default query will be like:
public IQueryable GetEmployee()
{
return this.ObjectContext.Employees;
}
With objectSet, I can apply include on the result like:
return this.ObjectContext.Employees.Include("Department");
Then I create a stored procedure say MySearchForEmployee and import it as function. the result is mapped to entity Employee. When call the function, the result will be ResultSet, not ObjectSet.
I want to similar method available for domain service by call the stored procedure like:
public IQueryable<Employeer> GetMySearch(string keyword)
{
return this.ObjectContext.MySearchForEmployee(keyword).Include("Department");
}
But I can't becuase above code event can't pass syntax checking.
I tried following way to convet the result type:
var results = this.ObjectContext.MySearchForEmployee(keyword);
var objsets = (ObjectSet<Employee>) results;
then I got error as:
Cannot convert type 'System.Data.Objects.ObjectResult' to 'System.Data.Objects.ObjectSet'
How to implement this request?
There is no reason to use an ObjectSet, because you cannot include multiple entity sets in one query from a stored procedure. This is not supported in the Entity Framework.
You could try the EFExtensions project, it has extensions to load multiple entity sets from one query.