LINQ SQL Select from list using partial match - c#

I have a list wbsList containing the current elements:
SS-B23813
SS-B23814
I want the SQL lookup to retreive all wbs elements that starts with those numbers to be listed, so I use this code:
var q =
from a in MESdb.GetTable<t_SAP_Order>()
where wbsList.Contains(a.WbsElement)
orderby a.WbsElement, a.OrderDescription
select a;
This results in nothing, because it only shows exact matches. All my wbs'es has a longer string (SS-B23813-24-1-15-06-100)
How can I use the list as a partial search criteria?
UPDATE:
When I change the code to Dunth's answer, I get the following error:
Local sequence cannot be used in LINQ to SQL implementations of query operators except Contains operator.
I wonder if this error comes because of some error when I try to display the result in a datagrid:
caseGrid.DataSource = q.Select(o => new
{
Workcenter = o.MainWorkCenter,
SO = o.Ordr,
Description = o.OrderDescription,
SerialNumber = o.SerialNumber,
BasicFinish = o.BasicFin
}).ToList();

Try this to find where it might not be at the start.
var q = MESdb.GetTable<t_SAP_Order>()
.Where(a => wbsList.Any(b => a.WbsElement.Contains(b)))
.OrderBy(a => a.WbsElement)
.ThenBy(a => a.OrderDescription).ToList();

Contains does a sql IN(...), you want a sql LIKE so use wbList.StartsWith(a.WbsElement)

Related

Does my LINQ query provide distinct SampleNumbers based off the code and LINQPad output provided?

I'm trying to use LINQPad to see outputs of my queries I'm writing for a C# WinForms application. I'm more just confused on how to interpret the outcome on a Dump() method and what is happening behind the scenes.My intended outcome is to have one SampleNumber per group of SampleData. SampleData is coming out of the database as a string split by commas.
Also, please spare me; I know how I name stuff is horrible and I'm planning to adjust once I get the data coming out correctly!
Here is my initial query:
var thinthroughoutQuery = (from a in ThicknessBlobs
join b in SummaryDataItems on a.SampleNumber equals b.SampleNumber
where (a.Source == "Thickness[0,0]")
&& b.TopBottomStatusFK == 3
orderby a.PKId descending
select a).Take(1000).ToList();
Here is where I attempt to take the string of SampleData, cut it at the delimiter, group by SampleNumber, and parse it as an integer:
var intThinThroughoutQuery = thinthroughoutQuery.Select(row => new { SampleNumber = row.SampleNumber, Value = row.SampleData.Split(",").Select(int.Parse) })
.SelectMany(group => group.Value.Select(value => new { group.SampleNumber, SampleData = value })).ToArray();
Here is the output from using Dump() in LINQPad:
To me, this appears like there are not distinct SampleNumbers and that each piece of SampleData separately maps to a repeating SampleNumber.
For further clarification, I want to be able to access the data and have it be like this:
Rather than:
You are missing GroupBy/ToLookup after flattening with SelectMany:
var intThinThroughoutQuery = thinthroughoutQuery.Select(row => new { SampleNumber = row.SampleNumber, Value = row.SampleData.Split(",").Select(int.Parse) })
.SelectMany(group => group.Value.Select(value => new { group.SampleNumber, SampleData = value }))
.ToLookup(row => row.SampleNumber, row => row.SampleData);

C#, Sorting a LINQ result alphabetically then, sort it according to Search Key

I'm retrieving data from a database using Entity Framework.
The result is filtered by a value entered in a Search TextBox.
var searchKey = this.TextBoxSearch.Text;
var products = this.databaseManager.Products.Where(x => x.Name.Contains(searchKey)).Select(x => x.Name);
Then the the result is sorted alphabetically.
products = products.OrderBy(x => x);
Now I want to sort the result in a way that; Results containing the search key at their beginning come before those containing the search key somewhere else in the text.
Example:
When the user types "iP"
The filtered results should be as bellow :
iPhone 4S, iPhone 5, All in one iP Phone ......
Of course in normal cases All in one iP phone is the first item in the list. because the results are sorted alphabetically. But in my case. the user's search key must be dominant.
Is this possible using C# Linq [.NET 4.5], Or in SQL Server ? if this can be done with an SQL query it's also good.
This should work:
var ordered = products.OrderBy(p => p.IndexOf("iP"));
var products = this.databaseManager.Products.Where(x => x.Name.Contains(searchKey)).Select(x => new {Name=x.Name,Index=x.Name.IndexOf(searchKey)}).OrderBy(a=>a.Index).ToList();
This should work in you case :
products = products.OrderBy(p => p.StartsWith("iP") ? 1 : 2).ThenBy(p => 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.

Converting SQL statement using SUM() to Linq/Entity Framework

I'm trying to figure out how to convert the following SQL statement to Entity Framework using Linq:
SELECT SUM(Column1) AS Correct
, SUM(Column2) AS Incorrect
, UserName
FROM Stats
WHERE (StatType = 0)
GROUP BY UserName
ORDER BY UserName
For the purposes of this question, all the column types in the DB are type INT, and there are multiple rows of data per user. I basically want 3 columns in my output, with the total of correct & incorrect selections for each user.
It seems like such a simple SQL statement but whatever I try in something like LinqPad, I always get errors. I must be missing something relatively simple. As soon as I start add a ".Sum" clause I get compilation errors etc.
Stats.Where(s => s.StatType == 0)
.GroupBy(s => s.UserName)
.Select(x => new { Correct = x.Column1
, Incorrect = x.Column2
, User=x.UserName})
.ToList()
The following should do the trick:
Stats.Where(s => s.StatType == 0)
.GroupBy(s => s.UserName)
.Select(x => new { Correct = x.Sum(y => y.Column1),
Incorrect = x.Sum(y => y.Column2),
User = x.Key})
.ToList();
Please note that GroupBy returns an IEnumerable<IGrouping<TKey, TValues>>.
That means that the x inside the Select is an IGrouping<TKey, TValues>. That in turn is basically just an IEnumerable<T> that contains all rows of that group along with the key of this group.
So, to get the sum of all items in a group, you need to use Sum on the grouping and specify which columns to sum as a parameter to the Sum method.

Mixing LINQ to SQL with properties of objects in a generic list

I am trying to accomplish something like this query:
var query = from a in DatabaseTable
where listOfObjects.Any(x => x.Id == a.Id)
select a;
Basically, I want to filter the results where a.Id equals a property of one of the objects in the generic list "listOfObjects". I'm getting the error "Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator."
Any ideas on how to filter this in an easily readable way using "contains" or another method?
Thanks in advance.
Just project your local list into a list of the specific items you need to filter on:
var listOfIds = listOfObjects.Select(o => o.Id);
var query =
from a in DatabaseTable
where listOfIds.Contains(a.Id)
select a;
var listOfIds = listOfObjects.Select(x => x.Id).ToList();
var query = from a in DatabaseTable
where listOfIds.Contains(a.Id)
select a;

Categories

Resources