LINQ to Entities does not recognize the method - Include + Where - entity-framework

I have this working Code
var h = db.MyTable.Include("Children").Include("Parent").ToList();
but when I add where condition
var h = db.MyTable.Include("Children").Include("Parent").Where(x => x.Country==Session["country"].ToString()).ToList();
it throws me an error
LINQ to Entities does not recognize the method 'System.Object get_item (System.String)' method , and this method cannot be translated into a store expression.
How can i rewrite it ? Im beginner :-)
Thank you

This is caused by your Where-Expression. You should only use variables in there or call methods that can be translated to SQL.
First, save your Session value in a variable:
var country = Session["country"].ToString();
Then use country in your Where-Expression.
MSDN provides a list of methods you can use inside LINQ to SQL expressions and how they are mapped to SQL functions.

try this:
var t = Session["country"].ToString();
var h = db.MyTable.Include("Children").Include("Parent").Where(x => x.Country==t).ToList();
only activities can be parsed into expression-tree that is supported by your provider

Related

How to refactor parts of an EF select

Let's say I have the following EF code:
context.Employees.Select(e => e
{
FullName = e.FirstName + " " + e.LastName,
StartDate = e.StartDate,
... // Grab other data
};
Now maybe I notice that I construct the full name in multiple places, but would like in centralized. Is it possible to refactor this?
If I make it a method or a Func, I get EF errors, because it can't translate it into SQL.
NOTE: This is a simple example, assume it can get much more complicated with "Select"s, "Where"s, whatever in the assignment, so adding a ToList and then running additional code would be suboptimal and does not fit the definition of refactoring since I would have to change functionality and not just make it more maintainable.
One solution is to use the AsExpandable method from LinqKit:
Expression<Func<Employee,string>> fullName = e => e.FirstName + " " + e.LastName;
context.Employees.AsExpandable().Select(e => e
{
FullName = fullName.Compile().Invoke(e),
StartDate = e.StartDate,
... // Grab other data
};
From the linked article:
Compile is an inbuilt method in the Expression class. It converts the
Expression into a plain Func which
satisfies the compiler. Of course, if this method actually ran, we'd
end up with compiled IL code instead of an expression tree, and LINQ
to SQL or Entity Framework would throw an exception. But here's the
clever part: Compile never actually runs; nor does LINQ to SQL or
Entity Framework ever get to see it. The call to Compile gets stripped
out entirely by a special wrapper that was created by calling
AsExpandable, and substituted for a correct expression tree.
Alternatively, you could look into creating an Model Defined Function with Entity Framework. There's also the Microsoft.Linq.Translations library if you want to define a FullName property on the Employee class itself.
I think the better centralized way to do it in the entity class itself. You can add ReadOnly property to your entity class which should be NotMapped to the database to return required formatted data.
Public class Employee
{
//...
public string fullName{get { return FirstName + " " + LastName;}}
}

MongoDB C# - update using custom strongly-typed objects not allowed?

I am trying to perform an update using strongly-typed objects. For example,
public void setAppointmentPrefs(string UserName, IEnumerable<AppointmentInfo> info)
{
var query = new QueryDocument {{ "ProviderId", UserName}};
var update = Update.Set("Prefs",prefs); // prefs.toList() gives same error
// providerprefs initialized in constructor
providerprefs.Update(query, update);
}
I receive a compiler error saying:Error 14 The best overloaded method match for 'MongoDB.Driver.Builders.Update.Set(string, MongoDB.Bson.BsonValue)' has some invalid arguments
Obviously the Mongo driver will not let me update based on my own object (whether as IEnumerable or prefs.toList()), which seems a contrast from the way it permits me to insert or query with custom objects. Surely I am missing something obvious that would permit me to avoid deserializing, weakly typing then creating a generic BsonDocument!! TIA.
You can do an Update based on your own types! Have you tried using the typed Query and Update builders?
Try something like this:
var query = Query<AppointmentInfo>.EQ(i => i.ProviderId, userName);
var update = Update<AppointmentInfo>.Set(i => i.Prefs, info.Prefs);
Not sure I got the types and everything write from your partial code, but that should give you the general idea.
Let me know if you have any further questions.
I know this has been answered but I for one don't fully understand Roberts answer.
All I did is call the "ToBsonDocument()" method for it to except the object as a parameter
So:
customObject.ToBsonDocument()
If you have an array of objects inside a document:
var query = Query.EQ("_id", ObjectId.Parse(id.ToString()));
var update = Update.Push("ArrayOfObjects", customObject.ToBsonDocument());
collection.Update(query, update);

EF4.1 Code First: Stored Procedure with output parameter

I use Entity Framework 4.1 Code First. I want to call a stored procedure that has an output parameter and retrieve the value of that output parameter in addition to the strongly typed result set. Its a search function with a signature like this
public IEnumerable<MyType> Search(int maxRows, out int totalRows, string searchTerm) { ... }
I found lots of hints to "Function Imports" but that is not compatible with Code First.
I can call stored procedures using Database.SqlQuery(...) but that does not work with output parameters.
Can I solve that problem using EF4.1 Code First at all?
SqlQuery works with output parameters but you must correctly define SQL query and setup SqlParameters. Try something like:
var outParam = new SqlParameter();
outParam.ParameterName = "TotalRows";
outParam.SqlDbType = SqlDbType.Int;
outParam.ParameterDirection = ParameterDirection.Output;
var data = dbContext.Database.SqlQuery<MyType>("sp_search #SearchTerm, #MaxRows, #TotalRows OUT",
new SqlParameter("SearchTerm", searchTerm),
new SqlParameter("MaxRows", maxRows),
outParam);
var result = data.ToList();
totalRows = (int)outParam.Value;

How call a custom method in lambda expression . I Use Entity Framework 4 . Stored expression error

Is it possible to call a custom method in a lambda expression.?
//Address a : It's an Entity
public string AddressConstructor(Address a)
{
return a.City + "," + a.Province;
}
var Test = _db.MyTableTest.Select( t => new ViewModel
{
MyID = t.ID,
StringAddress = AddressConstructor(t.Addr)
};
You should be able to accomplish this using LINQKit to inline your expression into the expression tree.
http://www.albahari.com/nutshell/linqkit.aspx
This will cause the concatanation you're attempting to be run on the SQL Server, not in memory (as described in the other answer). SQL Server of course knows how to concatanate strings, but if your AddressConstructor did something else that SQL Server doesn't understand, then this approach would not work and you would indeed need to perform your custom method in memory using the approach described in the other answer.
Essentially LINQKit will flatten the tree so it actually gets executed as:
var Test = _db.MyTableTest.Select( t => new ViewModel
{
MyID = t.ID,
StringAddress = t.Addr.City + "," + t.Addr.Province
};
which EF should have no problem executing (and the concatenation should happen on the SQL Server).
You need to call AsEnumerable so that the projection is executed locally:
var Test = _db.MyTableTest.AsEnumerable()
.Select( t => new ViewModel
{
MyID = t.ID,
StringAddress = AddressConstructor(t.Addr)
};
Otherwise, the Queryable.Select method is used instead of Enumerable.Select, which causes Entity Framework to try to translate the lambda expression to a SQL query (which of course is not possible in that case)

Generated SQL with PredicateBuilder, LINQPad and operator ANY

I previously asked a question about chaining conditions in Linq To Entities.
Now I use LinqKit and everything works fine.
I want to see the generated SQL and after reading this answer, I use LinqPad.
This is my statement:
var predProduct = PredicateBuilder.True<Product>();
var predColorLanguage = PredicateBuilder.True<ColorLanguage>();
predProduct = predProduct.And(p => p.IsComplete);
predColorLanguage = predColorLanguage.And(c => c.IdColorEntity.Products.AsQueryable().Any(expr));
ColorLanguages.Where(predColorLanguage).Dump();
The code works in VS2008, compile and produce the correct result set, but in LinqPad, I've the following error:
NotSupportedException: The overload query operator 'Any' used is not Supported.
How can I see the generated SQL if LINQPad fails?
EDIT
If I write
var predColorLanguage = PredicateBuilder.True<ColorLanguage>();
predColorLanguage = predColorLanguage.And(c => c.IdColorEntity.Products.Any((p => p.IsComplete));
ColorLanguages.Where(predColorLanguage).Dump();
works... WTF?
As you're using LINQKit, you can make this work by calling Compile() on the expression that feeds the EntitySet, and then calling AsExpandable() on the main query:
var predProduct = PredicateBuilder.True<Product>();
var predColorLanguage = PredicateBuilder.True<ColorLanguage>();
predProduct = predProduct.And(p => p.IsComplete);
predColorLanguage = predColorLanguage.And (
c => c.IdColorEntity.Products.Any(predProduct.Compile()));
ColorLanguages.AsExpandable().Where(predColorLanguage).Dump();
As explained in the LINQKit article, the Compile method never actually runs: AsExpandable strips it out and modifies the expression tree so that it works with LINQ to SQL.