Sql Query to Linq Query - c#

I have written an sql qyery like
SELECT TOP 1000
[tlotWeight]
,[TEU]
,[SeaAirFlag]
,CASE
WHEN [SeaAirFlag]='SEA' OR [SeaAirFlag]='Sea'
then [TEU]
else [tlotWeight] end as Volume
FROM [LogisticsBI].[dbo].[GoldenVolume]
I want it to convert it to linq c# query,I have tried something like this
(from t in db.GoldenVolumes
select new { Volume=(t.SeaAirFlag=="SEA"|| t.SeaAirFlag=="Sea")?t.TEU: t.tlotWeight)}
).Take(10000).Distinct()
but its showing some syntax error in linqpad
Please help me to correct way in linq to write this query

Well, I see problem with brackets here (opened one time and closed two times):
select new { Volume = (t.SeaAirFlag=="SEA" || t.SeaAirFlag=="Sea") ? t.TEU : t.tlotWeight)}
It looks like this should be either
select new { Volume = ((t.SeaAirFlag=="SEA" || t.SeaAirFlag=="Sea") ? t.TEU: t.tlotWeight)}
or (it's up to you)
select new { Volume = (t.SeaAirFlag=="SEA" || t.SeaAirFlag=="Sea") ? t.TEU: t.tlotWeight }

The error is pretty straightforward you have misarranged your round brackets.
t.tlotWeight)}) is wrong instead it should be t.tlotWeight})
Its better to split them to next lines for more clearity.
var res = (from t in db.GoldenVolumes
select new
{
Volume = (t.SeaAirFlag.ToUpperInvariant().Contains("SEA")) ?
t.TEU : t.tlotWeight
})
.Take(10000)
.Distinct();

Related

Comparing two counts in LINQ

hi have a simple query that compares all sent out requests to those that have been downloaded.
i have a tsql that works perfectly like so:
select case when (select COUNT(*) from FileRecipient where File_ID = 3 and downloaded = 'Y')
= (select COUNT(*) from FileRecipient where File_ID = 3) then 'Y' else 'N' end
but would like to do it in LINQ.
any and all help would be appreciated. i tried the following, but obviously i'm a long way away from getting it right. this just gives me the first of the two counts. do i need to do two separate statements to get the second?
public static bool DownloadedByAll(int fsID)
{
using (SEntities ctx = CommonS.GetSContext())
{
var result = (from fr in ctx.FileRecipients
where fr.File_ID == fsID && fr.downloaded == "Y"
select fr.Recipient_ID).Count();
}
}
or would it just be simpler for me to use tsql within the entity framework for this?
This should get you the result you need
var result = ctx.FileRecipients
.Count(f=>f.File_ID == 3
&& f.downloaded == 'Y') == ctxt.FileRecipients
.Count(f=>f.File_ID == 3);

Returning results using LINQ and multiple 'keywords'?

I'm new to ASP.Net and LINQ. I have a small project I'm working on. It basically consists of a screen with four text boxes, a listview control and a search button with one database table.
Each text box represents a certain field: Author, Title, Publisher, and Price. What I envision is that a user would input text in one, or more, of the fields and hit the search button. The program would then return whatever results could be found that match the user's criteria.
If I were using an SQL statement, I'd just select every record that matches any of the input fields (i.e. SELECT author, title, publisher, price FROM books WHERE...). However, I'm not quite sure how to do this with LINQ.
So, does anyone have a starting point for me? I've seen LINQ examples with one field as a limiter on the search:
public void SimpleSearch()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var q =
from a in dc.GetTable<Books>()
where a.Title == "1984"
select a;
dataGridView1.DataSource = q;
}
But I can't seem to find any other examples that use more than one limiter on the search. I'm beginning to think it isn't possible. If so, can someone recommend a different way for me to accomplish what I'm trying to do? Basically, I just want to search the table for fields that match the user's input and return the results in a listview. Any help would be greatly appreciate.
You should be able to use || as an OR delimiter:
public void SimpleSearch()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var q =
from a in dc.GetTable<Books>()
where a.Title == "1984" || a.Author == "Stephen King" || a.Price == 5.99m
select a;
dataGridView1.DataSource = q;
}
You can also use && to do an AND search instead of ||
I like to use contains to make the search a little more fuzzy and also I like to set everything to lowercase so there is no case sensitivity issues when performing the search.
public void SimpleSearch()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var search = txtSearch.Text.ToLower();
var q =
from a in dc.GetTable<Books>()
where a.Title.ToLower() == search ||
a.Author.ToLower() == search ||
a.Author.ToLower().Contains(search) ||
a.Title.ToLower().Contains(search)
select a;
dataGridView1.DataSource = q;
}

A C# Linq to Sql query that uses SUM, Case When, Group by, outer join, aggregate and defaults

I've been searching for possible solutions and attempting this for several hours without luck. Any help will be greatly appreciated.
I've got a Sql statement which I'm trying to put together as a C# LINQ query.
Here is the working SQL:
SELECT up.UserProfileID
,up.FirstName
,up.LastName
,SUM(CASE WHEN ul.CompletionDate IS NULL THEN 0
ELSE ISNULL(ul.Score, 0)
END) AS TotalScore
FROM dbo.UserProfile up
LEFT OUTER JOIN dbo.UserLearning ul ON up.UserProfileID = ul.UserProfileID
WHERE up.ManagerUserProfileID IS NULL
GROUP BY up.UserProfileID, up.FirstName, up.LastName
I've tried several different ways but seem to end up with either a statement that doesn't return what I want or doesn't execute successfully
My current (non-working) code looks something like this:
var pd = from up in db.UserProfiles
join ul in db.UserLearnings on up.UserProfileID equals ul.UserProfileID into temp
from upJOINul in temp.DefaultIfEmpty(new UserLearning() { Score = 0 })
where up.ManagerUserProfileID.Equals(null)
group up by new
{
UserProfileID = up.UserProfileID,
FirstName = up.FirstName,
LastName = up.LastName,
TotalScore = up.UserLearnings.Sum(u => u.Score)
};
Thank you for any help
After several more attempts and further use of google I finally managed to get a working solution. I hope it'll be of use to someone else.
var pd = db.UserProfiles.AsEnumerable()
.Where(up => up.ManagerUserProfileID.Equals(null))
.Select(up => new
{
UserProfileID = up.UserProfileID,
FirstName = up.FirstName,
LastName = up.LastName,
TotalScore = up.UserLearnings
.Where(ul => ul.CompletionDate.HasValue && ul.Score.HasValue)
.DefaultIfEmpty()
.Sum(ul => ul != null && ul.Score.HasValue ? ul.Score : 0)
});
Not what you asked for, but if you have a working complex SQL query, that is fairly static, put it in a stored proc, and drag that SP to your LINQ DataContext.
The LINQ provider has to compile your query to sql every time it's called, and that takes time, and server CPU cycles. If it's a complex query, it can eat up significant resources. Also may miss some optimizations you can do with straight SQL.
Unless of course there is a purpose to it.
If you have ORM problem, grap the actual SQL commands, take a look at it, and compare with what you want to achieve. Can you show the generated SQL as well, so we can find the difference easier?

LINQ-To-SQL - slow query

I'm just wondering if anyone can offer any advice on how to improve my query.
Basically, it'll be merging 2 rows into 1. The only thing the rows will differ by is a 'Type' char column ('S' or 'C') and the Value. What I want to do is select one row, with the 'S' value and the 'C' value, and calculate the difference (S-C).
My query works, but it's pretty slow - it takes around 8 seconds to get the results, which is not ideal for my application. I wish I could change the database structure but I can't sadly!
Here is my query:
var sales = (from cm in dc.ConsignmentMarginBreakdowns
join sl in dc.SageAccounts on new { LegacyID = cm.Customer, Customer = true } equals new { LegacyID = sl.LegacyID, Customer = sl.Customer }
join ss in dc.SageAccounts on sl.ParentAccount equals ss.ID
join vt in dc.VehicleTypes on cm.ConsignmentTripBreakdown.VehicleType.Trim() equals vt.ID.ToString() into vtg
where cm.ConsignmentTripBreakdown.DeliveryDate >= dates.FromDate && cm.ConsignmentTripBreakdown.DeliveryDate <= dates.ToDate
where (customer == null || ss.SageID == customer)
where cm.BreakdownType == 'S'
orderby cm.Depot, cm.TripNumber
select new
{
NTConsignment = cm.NTConsignment,
Trip = cm.ConsignmentTripBreakdown,
LegacyID = cm.LegacyID,
Costs = dc.ConsignmentMarginBreakdowns.Where(a => a.BreakdownType == 'C' && a.NTConsignment == cm.NTConsignment && a.LegacyID == cm.LegacyID && a.TripDate == cm.TripDate && a.Depot == cm.Depot && a.TripNumber == cm.TripNumber).Single().Value,
Sales = cm.Value ?? 0.00m,
Customer = cm.Customer,
SageID = ss.SageID,
CustomerName = ss.ShortName,
FullCustomerName = ss.Name,
Vehicle = cm.ConsignmentTripBreakdown.Vehicle ?? "None",
VehicleType = vtg.FirstOrDefault().VehicleTypeDescription ?? "Subcontractor"
});
A good place to start when optimizing Linq to SQL queries is the SQL Server Profiler. There you can find what SQL code is being generated by Linq to SQL. From there, you can toy around with the linq query to see if you can get it to write a better query. If that doesn't work, you can always write a stored procedure by hand, and then call it from Linq to SQL.
There really isn't enough information supplied to make an informed opinion. For example, how many rows in each of the tables? What does the generated T-SQL look like?
One thing I would suggest first is to take the outputted T-SQL, generate a query plan and look for table or index scans.

LINQ Query to Return multiple results

I am trying to write a textbox that will search on 5 DB columns and will return every result of a given search, ex. "Red" would return: red ball, Red Williams, etc. Any examples or similar things people have tried. My example code for the search.
Thanks.
ItemMasterDataContext db = new ItemMasterDataContext();
string s = txtSearch.Text.Trim();
var q = from p in db.ITMSTs
where p.IMITD1.Contains(s) ||
p.IMITD2.Contains(s) ||
p.IMMFNO.Contains(s) ||
p.IMITNO.Contains(s) ||
p.IMVNNO.Contains(s)
select p;
lv.DataSource = q;
lv.DataBind();
"q" in your example will be an IQueryable<ITMST>. I don't think the Datasource property of WebControl know what to do with that. try writing that line as:
lv.DataSource = q.ToList();
You can do something like this (syntax may be off )
using(var db = new ItemMasterDataContext())
{
var s = txtSearch.Text.Trim();
var result = from p in db.ITMSTs select p;
if( result.Any(p=>p.IMITD1.Contains(s))
lv.DataSource = result.Where(p=>p.IMITD1.Contains(s))
else if ( result.Any(p=>p.IMITD2.Contains(s))
lv.DataSource = result.Where(p=>p.IMITD1.Contains(s))
lv.DataBind();
}
or you might want to use this Link or this Link from MSDN.
Happy Coding!!
What you have is generally what people would do using linq. If you wanted to get more complex and use database wild cards then take a look at the SqlMethods class in System.Data.Linq.
# James Curran
You can assign the DataSource property q and it will work fine. The only different is when the query gets executed.

Categories

Resources