EF using LINQ trying Contains In passing in a Array - c#

Is there a better way to write this CONTAINS from an ARRAY?
I am passing a string/array into my LINQ statement. In SQL the code that is working is
SELECT * FROM dbo.option1
WHERE option1Code IN ('9841','V237','SV02','2057')
In EF using LINQ I am trying
using (var ctx = new ProductEntities())
{
//--------------------------------------------------------------------//
string csvSKU = '984,237,102,207';
string[] mArray = csvSKU.Split(',');
var results = (from o in ctx.option1
join p in ctx.Products on o.option1Code equals p.productSKU
where mArray.Contains(o.option1Code)
orderby o.option1Sort
select o).Distinct().ToList();
return results;
}

This looks perfectly fine and should result in similar SQL as you posted (at least for the Contains part).
Also not really sure what your join is for right now - are there any option codes that have no entry in the Products table / productSKU?

Related

Using LINQ to get all results where ID in dictionary

i have something like this now, which only searches for 1 LabID
List<Expense> lstExpenses = (from l in ctx.Expenses
where l.datLab.Lab_ID == labID
select l).ToList<Expense>();
how do i return all results where Lab_ID is in a dictionary i have:
the followin functions returns a dictionary value: report.GetLabChildren(labID, "All"); is in <short>,<string> format. i only want to search on the <short>
If you want to do the filtering in linq to objects:
var query = ctx.Expenses.AsEnumerable()
.Where(expense => dictionary.ContainsKey(espense.Lab_Id));
If you want something that can be translated to the database:
var ids = dictionary.Keys.ToList();
var query = ctx.Expenses
.Where(expense => ids.Contains(expense.Lab_Id));
Note this will only work if you have less than a few thousand keys in your dictionary, as it is translated to a SQL IN clause. If you have more than that either upload them to a temporary table and join the two tables, or pull the entire Expenses table and use the linq to objects version.
List<Expense> lstExpenses = (from l in ctx.Expenses
where report.GetLabChildren(labID, "All").Keys.Contains(i.Lab_ID)
select l).ToList<Expense>();
I'm not 100% sure what you're asking about, but looks like you're looking for ContainsKey method:
var values = report.GetLabChildren(labID, "All");
List<Expense> lstExpenses = (from l in ctx.Expenses
where values.ContainsKey(l.datLab.Lab_ID)
select l).ToList<Expense>();
I'm not sure, but there is a chance that it won't work with LINQ to Entities. Use following if it happens:
List<Expense> lstExpenses = (from l in ctx.Expenses
where values.Keys.Contains(l.datLab.Lab_ID)
select l).ToList<Expense>();

Only primitive types are supported in this context

I have the following extract of code and I get the above error. This is a really simple query and of course works perfectly in SQL. What am I missing?
public IEnumerable<PAYSHIST> GetPayrollCriteria(string COID, IEnumerable<ASITE> sites)
{
var recs = from p in _entities.PAYSHISTs
join a in sites on p.SITE_CODE equals (a.SALES_ACC + a.SITE_NUMBER.ToString("000"))
select p;
return recs;
}
You cant join an in memory collection with a database table. Try writing the query as follows instead using Contains:
var recs = from p in _entities.PAYSHISTs
where sites.Select(a => a.SALES_ACC + a.SITE_NUMBER.ToString("000"))
.Contains(p.SITE_CODE)
select p;

LINQ where db table does not contain in memory list elements

I have seen these StackOverflow Answers but they do not produce the same results when the filtering list is in memory.
I have a list of Ids. I want to remove any IDs that exists in the database, so that I am left with a list of IDs that need to be added. In other words, I need to perform a where not in SQL query, using Linq-To-Entities. The problem is, instead of producing that SQL, these methods each produce a SQL query per list item.
var providerIds = new [] {"1130", "1", "16"};
Method 1:
var missingProviders = (from provider in providerIds
where !JobProviders.Any(p => p.JobProviderID == provider)
select provider).ToList();
Method 2:
var missingProviders = (from provider in providerIds
where !(from p in JobProviders select p.JobProviderID).Contains(provider)
select provider).ToList();
Is there a way to structure the LINQ query such that it produces the intended not in form, or are these the only solutions?
What about something like
var providersInDb = (from provider in JobProviders
where providerIds.Contains(provider.JobProviderID)
select provider.JobProviderID).ToList();
var missingProviders = providerIds.Where(p => !providersInDb.Contains(p))
Tricky. I don't have my tools in front of me, so I don't know how this will pan out exactly.
var dbProviderIds = JobProviders.Select(p => p.JobProviderId);
var allProviders = dbProviderIds.Union(providerIds).Distinct();
var missing = allProviders.Except(dbProviderIds);
On the DB, get all the provider Ids, then combine that with the in-memory ones. Then remove the ones that are known on the database.

LINQ Projected Filtering C#

I want to filter my LINQ query based on an included table but am having some trouble.
Here is the original statement, which works:
return
this.ObjectContext.People.
Include("Careers").
Include("Careers.Titles").
Include("Careers.Titles.Salaries");
Now I'm trying to filter on Careers using projected filtering but am having trouble. It compiles but it leaves out the Titles and Salaries tables, which causes runtime errors, and I can't seem to add those tables back in:
var query1 = (
from c in
this.ObjectContext.People.
Include("Careers").
Include("Careers.Titles").
Include("Careers.Titles.Salaries")
select new
{
c,
Careers = from Careers in c.Careers
where Careers.IsActive == true
select Careers
});
var query = query1.AsEnumerable().Select(m => m.c);
return query.AsQueryable();
How can I include the titles and salaries tables in the filtered query?
You can simplify your query considerably, which should resolve your issue. I'm assuming that you want all people with at least 1 active career:
var query =
from c in
this.ObjectContext.People.
Include("Careers").
Include("Careers.Titles").
Include("Careers.Titles.Salaries")
where c.Careers.Any(c => c.IsActive);
return query;
I would try something like,
var query = from p in ObjectContext.People
join c in ObjectContext.Careers on p equals c.Person
where c.IsActive
select p;

C# Linq to SQL - IEnumerable Join Two Data Tables/Context

I am using Visual Studio 2010, ASP.NET MVC 3, with a SQL 2008 R2 Database.
This, I believe is a simple task but I don't exactly know how to word it. This is the current code I have.
public static IEnumerable GetAPCBundledCodesData(string CPTCode)
{
var result = (from item in new VADataContext().CPT2MODs
where item.CPT == CPTCode
select new { item.MOD }).ToList();
return result;
}
This pulls a list of items in the CPTSMODs table and returns it. What I would like to do is take that result and get another list with matches to every item with the same value in another table called Modifiers with the same field MOD. I'm not sure how to do this part.
I hope I've explained this well enough. Let me know if there is any clarification needed.
I've continued to look for an answer and found that my problem is I can have two DataContext in on statement. I'm not even sure if this would work if it wasn't two DataContext but I tried doing this:
public static IEnumerable GetAPCBundledCodesData(string CPTCode)
{
var result = (from mod in new VADataContext().MODIFIERs
join cpt2mod in new VADataContext().CPT2MODs on mod.MOD equals cpt2mod.MOD
where cpt2mod.CPT == CPTCode
select new { mod.MOD, mod.SHORT }).ToList();
return result;
}
This resulted in an error saying I can't pull data from two different sources. Is there a different way to handle it?
Here is some sample data to show what is going on here.
Table CPT2MOD
CPT** MOD**
31624 TC
31624 A
31624 DC
99213 B
99213 T
00100 AS
Table MODIFIERs
MOD** SHORT**
TC TC Desc
A A Desc
DC DC Desc
B B Desc
T T Desc
AS AS Desc
A CPT Code will be passed to GetAPCBundledCodesData (ex 99213) and it will look for all MOD values associated with it from the CPT2MOD table (B, T). Then it will return those MOD from the MODIFIERs table along with the description. (B, B Desc; T, T Desc).
I hope you can see what I am asking better now.
Solution
public static IEnumerable GetAPCBundledCodesData(string CPTCode)
{
using (var dc = new VADataContext()){
var result = (from a in dc.CPT2MODs
where a.CPT == CPTCode
join b in dc.MODIFIERs on a.MOD equals b.MOD
select new { b.MOD, b.SHORT }).ToList();
return result;
}
}
Use only one ObjectContext - and use a using (very important):
using(var dc = new VADataContext()){
var result = (from mod in dc.MODIFIERs
join cpt2mod in dc.CPT2MODs on mod.MOD equals cpt2mod.MOD
where cpt2mod.CPT == CPTCode
select new { mod.MOD, mod.SHORT }).ToList();
return result;
}
As an aside - entity framework typically doesn't call the classes it generates DataContext - that's a Linq to SQL thing - are you sure that you're actually using entity framework? It doesn't actually have any bearing on the fix, it's just a request for clarification.

Categories

Resources