Linq-to-Entities query result that used params from multiple tables/Dbs - linq

Greetings Everyone
I am using EF6 and VS13 Free Community.
I followed a database First Approach.
I currently have a project (.net mvc) that contains multiple databases and tables
i am using the Entities & Linq queries and i couldn't figure out how to use the result of the queries i create when it's inside an if statement i saw solution but it only works when i use a single table not multiple ones. Example :
var query = from varA in db1.table_name
from varB in db2.table_name
where
varA.X = varB.X
select new
{
varA.stuff,
varB.something
}

Resolved didn't search deep enough
a foreach did it for me
foreach (var result in query)
{
...
}

Related

Create a Dynamic Entity Framework Where Query

At runtime I have a dynamic list of "Parent" ids i need to query against one of my entity tables, using LINQ how would I generate the query at run time? Currently am (VERY SLOWLY) looping over my list of ID's and performing a separate query to the database using the Where method. Is there an API that will allow me to build a single WHERE statement that in essence is appending "&& value = something" as I would have if I was writing the SQL myself?
Currently what i do looks like this
foreach(var parent in parents)
{
col.AddRange(context.LocalAuthorities.Where(c => c.Parent.ID == parent.ID).ToList());
}
If your goal is to replace multiple iterative queries by one query, you can use this approach:
var allParentIds = parents.Select(p=>p.ID).ToList();
var result = context.LocalAuthorities.Where(c=> allParentIds.Contains(c.Parent.ID));
col.AddRange(result);

Linq To Entities 'Only primitive types or enumeration types are supported' Error

I am using LinqPad to test my query. This query works when the LInqPad connection is to my database (LInq to SQL) but it does not work when I change the connection to use my Entity Framework 5 Model.dll. (Linq to Entity). This is in C#.
I have two tables called Plan and PlanDetails. Relationship is one Plan to many PlanDetails.
var q = from pd in PlanDetails
select new {
pd.PlanDetailID,
ThePlanName = (from p in this.Plans
where p.PlanID == pd.PlanID
select p.PlanName)
};
var results = q.ToList();
q.Dump(); //This is a linqpad method to output the result.
I get this error "NotSupportedException: Unable to create a constant value of type 'Domain.Data.Plan'. Only primitive types or enumeration types are supported in this context." Any ideas why this only works with Linq to SQL?
basically it means you are using some complex datatype inside the query for comparison.
in your case i suspect from p in this.Plans where p.PlanID == pd.PlanID is the culprit.
And it depends on DataProvider. It might work for Sql Data Provider, but not for SqlCE data Provider and so on.
what you should do is to convert your this.Plans collection into a primitive type collection containing only the Ids i.e.
var integers = PlanDetails.Plans.Select(s=>s.Id).ToList();
and then use this list inside.
var q = from pd in PlanDetails
select new {
pd.PlanDetailID,
ThePlanName = (from p in integers
where p == pd.PlanID
select pd.PlanName)
};
I got this error when i was trying to null check for a navigational property in the entity framework expression
I resolved it by not using the not null check in the expression and just using Any() function only.
protected Expression<Func<Entities.Employee, bool>> BriefShouldAppearInSearchResults(
IQueryable<Entities.Employee> briefs, string username)
{
var trimmedUsername = NameHelper.GetFormattedName(username);
Expression<Func<Entities.Employee, bool>> filterExpression = cse =>
cse.Employee.Cars.All(c =>
c.Employee.Cars!=null && <--Removing this line resolved my issue
c.Employee.Cars.Any(cur => cur.CarMake =="Benz")));
return filterExpression;
}
Hope this helps someone!
This is a Linqpad bug if you like (or a peculiarity). I found similar behaviour myself. Like me, you may find that your query works with an ObjectContext, but not a DbContext. (And it works in Visual Studio).
I think it has to do with Linqpad's inner structure. It adds MergeAs (AppendOnly) to collections and the context is a UserQuery, which probably contains some code that causes this bug.
This is confirmed by the fact that the code does work when you create a new context instance in the Linqpad code and run the query against this instance.
If the relationship already exists.
Why not simply say.
var q = from pd in PlanDetails
select new {
pd.PlanDetailID,
ThePlanName = pd.Plan.PlanName
};
Of course i'm assuming that every PlanDetail will belong to a Plan.
Update
To get better results from LinqPad you could tell it to use your own assembly (which contains your DbContext) instead of the default Datacontext it uses.

When using entity framework Where does this syntax return all records locally before doing the where

db.AdDetails.Where( u => u.OwnerGUID == CurrentUserProviderKey)
I have an adDetails table that has an OwnerGUID field.
I want to pull out only ad details that belong to the currenly logged in user.
My query does not show any where clauses in the SQL when I look at it in the debugger.
Can someone help me figure out what is wrong with my statement and if all rows in the table will be brought back then all 10K records put though a where on the webserver?
I am really new to this.
Using the Where extension method will filter down the results.
Queries in Entity Framweork are not executed until you iterate over them. If you do:
var query = db.Where(u => u.OwnerGUID == key);
This does not execute the query. When you do the following:
var list = list.ToList();
OR
foreach( var item in query) { ... }
That is when the query will be executed in SQL. The results should be filtered with your WHERE clause at this point.

Create a linq subquery returns error "Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator"

I have created a linq query that returns my required data, I now have a new requirement and need to add an extra field into the returned results. My entity contains an ID field that I am trying to map against another table without to much luck.
This is what I have so far.
Dictionary<int, string> itemDescriptions = new Dictionary<int, string>();
foreach (var item in ItemDetails)
{
itemDescriptions.Add(item.ItemID, item.ItemDescription);
}
DB.TestDatabase db = new DB.TestDatabase(Common.GetOSConnectionString());
List<Transaction> transactionDetails = (from t db.Transactions
where t.CardID == CardID.ToString()
select new Transaction
{
ItemTypeID= t.ItemTypeID,
TransactionAmount = t.TransactionAmount,
ItemDescription = itemDescriptions.Select(r=>r.Key==itemTypeID).ToString()
}).ToList();
What I am trying to do is key the value from the dictonary where the key = itemTypeID
I am getting this error.
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
What do I need to modify?
This is a duplicate of this question. The problem you're having is because you're trying to match an in-memory collection (itemDescriptions) with a DB table. Because of the way LINQ2SQL works it's trying to do this in the DB which is not possible.
There are essentially three options (unless I'm missing something)
1) refactor your query so you pass a simple primitive object to the query that can be passed accross to the DB (only good if itemDescriptions is a small set)
2) In your query use:
from t db.Transactions.ToList()
...
3) Get back the objects you need as you're doing, then populate ItemDescription in a second step.
Bear in mind that the second option will force LINQ to evaluate the query and return all transactions to your code that will then be operated on in memory. If the transaction table is large this will not be quick!

DynamicObject LINQ query does't works with custom class!

DynamicObject LINQ query with the List compiles fine:
List<string> list = new List<string>();
var query = (from dynamic d in list where d.FirstName == "John" select d);
With our own custom class that we use for the "usual" LINQ compiler reports the error "An expression tree may not contain a dynamic
operation":
DBclass db = new DBclass();
var query = (from dynamic d in db where d.FirstName == "John" select d);
What shall we add to handle DynamicObject LINQ?
Does DBClass implement IEnumerable? Perhaps there is a method on it you should be calling to return an IEnumerable collection?
You could add a type, against which to write the query.
I believe your problem is, that in the first expression, where you are using the List<>, everything is done in memory using IEnumerable & Link-to-Objects.
Apparently, your DBClass is an IQueryable using Linq-to-SQL. IQueryables use an expression tree to build an SQL statement to send to the database.
In other words, despite looking much alike, the two statements are doing radically different things, one of which is allowed & one which isn't. (Much in the way var y = x * 5; will either succeed or fail depending on if x is an int or a string).
Further, your first example may compile, but as far as I can tell, it will fail when you run it. That's not a particular good benchmark for success.
The only way I see this working is if the query using dynamic is made on IEnumerables using Link-to-Objects. (Load the full table into a List, and then query on the list)

Resources