Dynamic Linq 'contains' clause without using placeholder - c#

The syntax given for contains clause is
ids = new int[] {1,2,3,4};
dataContext.Table.Where("#0.Contains(id)", ids);
But what I want is
dataContext.Table.Where("{1,2,3,4}.Contains(id)"); //getting exception here
[ERROR] Expression expected (at index 0)
I need this because the where clause my or may not use the contains method. it depends on how user acts.

so I got the answer for this after tinkering for sometime. So posting the answer here.
dataContext.Table.Where("new Int[]{1,2,3,4}.Contains(id)");
You can use whatever datatype you need. I use reflection to find datatype and use that accordingly.

try code:
int[] ids= {1,2,3,4};
dataContext.Table.Where(c=>c.ids.Contains(t.id)).ToList();
Or
var result= (from p in dataContext.Table.AsEnumerable()
join q in ids on p.id equals q
select p).Distinct() .ToList();

Related

What is the linq equivalent of the below sql query

select Productid from categories where `categoryname` in `('abc','def','ghi')`;
I have tried this:
var res = from catg in db.Categories where catg.CategoryId.ToString().Contains(SelectedProducts) select catg;
But this doesnt seem to work...
Assuming SelectedProducts is an array of product ids (integers):
var cats = db.Categories.Where(o => SelectedProducts.Contains(o.CategoryId));
var pids = cats.Select(o => o.ProductId);
Reason: SQL IN operator is implemented oppositely in LINQ to SQL. The question highlights a common mistake in LINQ developers trying to translate from SQL, expecting an [attribute] [operator] [set] syntax.
Using an abstract set language we can highlight syntax differences
SQL uses a "Element is included in Set" syntax
LINQ uses a "Set contains Element" syntax
So any IN clause must be reverted using the Contains operator. It will translate to attribute IN (SET) anyways.
You need to use Contains on SelectedProducts
var res = from catg in db.Categories where
SelectedProducts.Contains(catg.categoryname) select catg.Productid;
Using method notation
var res = db.Categories.Where(catg => SelectedProducts
.Contains(catg.categoryname)).Select(catg.Productid);
The equivalence of a SQL IN with IEnumerable.Contains():
var res = from catg in db.Categories
where new[] {"abc","def","ghi"}.Contains(catg.categoryname)
select catg.Productid
Or lambda
db.Categories.Where(x => new[] {"abc","def","ghi"}.Contains(x.categoryname)).Select(c => c.ProductId);

Could not find an implementation of the query 'Select' not found

My error is:
Could not find an implementation of the query pattern for source type
'System.Data.Entity.Database'. 'Select' not found.
My relevent code is:
DatabaseEntities db = new DatabaseEntities();
var whichUi = from UiType in db.Database
select AdvancedUi;
I am using the linq import (common answer on other threads).
I think your error is that you try to select something from .Database directly, not from the table. Instead of this code:
from UiType in db.Database
try out something like this:
from UiType in db.UiTypes
select UiType.AdvancedUi;
This should work as the table UiTypes will implemet the IEnumerable interface.
You should put your table name after the in keyword.
UiType is just a placeholder, and can be anything you want. Please, pay attention to the select clause - you must use the placeholder there, not the table name.
In my case, I resolved the error by changing:
var results = db.MyStoredProc().Select(x => x);
Or,
var results = from x in db.MyStoredProc()
select x;
To,
var results = db.MyStoredProc();
HTH.
The whole logic behind the query syntax/fluent syntax is to select an object as a whole or to select a property of an object.
Look at this following query:
var result = (from s in _ctx.ScannedDatas.AsQueryable()
where s.Data == scanData
select s.Id).FirstOrDefault();
Please note that after the where clause I am selecting only the Id property of the ScannedData object.
So to answer your question, if AdvancedUi is a property of UiTypes class then your query should be more like:
var result = from UiType in db.UiTypes
select UiType.AdvancedUi;
Alternatively if you want to return all data from a table say ScannedDatas, then your query will be:
var listResult = (from d in _ctx.ScannedDatas
select d).ToList();
Hope this answers your question my friend.

Selecting with linq from 2 different objects

i want to select from 2 different objects in Linq in order to compare them. This is what i tried,
var myItem = (from abc in firstList.Value
from cds in secondList
where (abc.Key.theKey == cds.secondList.theSecondKey
select cds).SingleOrDefault();
although i get an error:
Type inference failed in the call to 'SelectMany'
If that's your exact query, it may just be because you've got unmatched brackets. Try this:
var myItem = (from abc in firstList.Value
from cds in secondList
where abc.Key.theKey == cds.secondList.theSecondKey
select cds).SingleOrDefault();
Admittedly I would probably rewrite that using a join - in most cases the join will be more efficient.
However, if that's not your exact query, please post a short but complete program which demonstrates the problem. It's not clear why cds would have a secondList property for example. A complete example demonstrating the problem would make this a lot simpler.
You have an opening paranthesis in more:
var myItem = (from abc in firstList.Value
from cds in secondList
where abc.Key.theKey == cds.secondList.theSecondKey
select cds
).SingleOrDefault();

How to do an "in" query in entity framework?

How can I do a select in linq to entities to select rows with keys from a list? Something like this:
var orderKeys = new int[] { 1, 12, 306, 284, 50047};
var orders = (from order in context.Orders
where (order.Key in orderKeys)
select order).ToList();
Assert.AreEqual(orderKeys.Count, orders.Count);
I tried using the Contains method as mentioned in some of the answers but it does not work and throws this exception:
LINQ to Entities does not recognize the method 'Boolean Contains[Int32](System.Collections.Generic.IEnumerable`1[System.Int32], Int32)' method, and this method cannot be translated into a store expression.
Try this:
var orderKeys = new int[] { 1, 12, 306, 284, 50047};
var orders = (from order in context.Orders
where orderKeys.Contains(order.Key);
select order).ToList();
Assert.AreEqual(orderKeys.Count, orders.Count);
Edit: I have found some workarounds for this issue - please see WHERE IN clause?:
The Entity Framework does not
currently support collection-valued
parameters ('statusesToFind' in your
example). To work around this
restriction, you can manually
construct an expression given a
sequence of values using the following
utility method:
I had the same problem and i solved like this
var orderKeys = new int[] { 1, 12, 306, 284, 50047};
var orders = (from order in context.Orders
where (orderKeys.Contains(order.Key))
select order).ToList();
Assert.AreEqual(orderKeys.Count, orders.Count);
Unfortunately the EF can't translate the queries others have suggested. So while those queries would work in LINQ to Objects, they won't work in LINQ to Entities.
So the solution is a little more involved.
However I have a blog post on this exact topic here. Essentially the solution is to use a little expression tree magic to build an big OR expression.
Hope this helps
Alex

How do I do a Contains() in DLINQ with a list of items?

I want to build a dlinq query that checks to see if a title has any number of items in it. I know you can do .Contains() with a list, but I need to check if the title contains any of the items, not if the items contain part of the title. For example: I have three items in the list "bacon, chicken, pork". I need the title of "chicken house" to match.
var results = (from l in db.Sites
where list.Contains(l.site_title)
select l.ToBusiness(l.SiteReviews)).ToList();
If I try the first 2 answers, I get an error "Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator."
The third solution gives me
Method 'System.Object DynamicInvoke(System.Object[])' has no supported translation to SQL."
Try the following. You can use a combination of Where and Any to search for substring matches.
var results = (from l in db.Sites
where list.Where(x => 0 != x.IndexOf(l)).Any()
select l.ToBusiness(l.SiteReviews)).ToList();
One way is to dynamically build a query as outlined here:
http://andrewpeters.net/2007/04/24/dynamic-linq-queries-contains-operator/
I finally figured it out. Thanks to my good buddy Cory for the help. There are two ways you can do it.
var resultSets = (from k in list
select (from b in db.Sites
where b.site_title.Contains(k)
select b.ToBusiness()).ToList<Business>()).ToList();
List<Business> all = new List<Business>();
for (int i = 0; i < resultSets.Count; ++i)
{
all.AddRange(resultSets[i]);
}
This is a linq query that will successfuly do what is stated. As well, you can also just build the sql query in plain text by hand.

Categories

Resources