Need help in Linq Query [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am rewriting a tool from old .net to .net 4.0 and am using Linq. I am new to Linq and became stuck when solving the following problem:
I have a table called UserInfo with all the columns needed. However, I need a specific data and need to do as follow but in Linq. Can someone please help me with Linq query syntax? Any help much be appreciated.
Thanks a lot in advance for any help with this matter.
SELECT DISTINCT a.liProviderKey
FROM UserInfo a INNER JOIN
UserInfo b ON a.strBusinessType = b.strBusinessType AND
(a.strCity = b.strCity AND a.strZip = b.strZip AND a.strState = b.strState AND
a.strCompanyName = b.strCompanyName AND (a.strDotNum = b.strDotNum OR
a.strFedTaxNum = b.strFedTaxNum OR
a.strPhone = b.strPhone)) OR
(a.strSSN = b.strSSN AND a.strLastName = b.strLastName AND a.strbusinessType='Consumer')
WHERE (b.liUserKey = #UserID AND a.fActive=1 AND a.fAuthenticated=1)

Using method syntax:
DataContext dc = new DataContext(ConnectionString);
var result = dc.UserInfos.Join(dc.UserInfos,
a => new { strBusinesssType == a.strBusinessType, ..., strSSN = a.strSSN },
b => new { strBusinesssType == b.strBusinessType, ..., strSSN = b.strSSN },
(a, b) => new { aTable = a, bTable = b })
.Where(o => o.bTable.liUserKey == #UserID && o.aTable.fActive == 1 && o.aTable.fAuthenticated == 1)
.Select(o => o.aTable.liProviderKey).Distinct();
Using query syntax:
var query = from a in UserInfos
join b in UserInfos on new { a.strBusinessType, ..., a.strSSN } equals new { b.strBusinessType, ..., b.strSSN }
where b.liUserKey == #UserID && a.fActive == 1 && a.fAuthenticated == 1
select a.liProviderKey;
query = query.Distinct();
If you want a complex comparison, you'll have to do the join in the where clause. Here you would remove the join and replace it with a second from (again, query syntax):
var query = from a in UserInfos
from b in UserInfos
where b.liUserKey == #UserID && a.fActive == 1 && a.fAuthenticated == 1 &&
((a.strBusinessType == b.strBusinessType) && ([rest of your conditions]))
select a.liProviderKey;
query = query.Distinct();

Related

How do I write SELECT FROM myTable WHERE id = (SELECT) in Linq?

How can I rewrite this SQL query in LINQ with a lambda expression?
SELECT
CO.*
FROM
COMPANY CO
WHERE
CO.ID = '5'
AND CO.ID <> (SELECT COMPANY_ID
FROM dbo.EMPLOYEE
WHERE USERNAME = 'ADMIN')
I tried the following code I think it is correct, but it is not working:
var obj1 = db.COMPANies
.Where(co => co.ID != co.EMPLOYEEs.SingleOrDefault(em => em.USERNAME == userName).COMPANY_ID && co.ID == iID);
Can you please help me?
Can I use
co.EMPLOYEEs.SingleOrDefault(em => em.USERNAME == userName).COMPANY_ID
inside the db.COMPANies.Where ??
I have read the question in: How do I write SELECT FROM myTable WHERE id = (SELECT) in Linq?
but it not help me.
EDIT :
Image table structure, Click here
Sorry for my bad english. Thanks!
I hope that you have objects of COMPANY table and EMPLOYEE table which will be having the data. On those objects, you can fire the below LINQ to achieve your results.
COMPANY.Select(x => x.Id == 5 && x.Id != EMPLOYEE.Where(z => z.USERNAME == "ADMIN").Select(g => g.COMPANY_ID).FirstOrDefault());
Don't forget to add using System.Linq;
Using lambda expression, you can try this
var comapaniesWhereUserIsAdmin = from e in db.EMPLOYEEs
where e.username='Admin'
select e.CompanyId;
var result = from c in db.Companies
where c.ID == iID && !comapaniesWhereUserIsAdmin.Contains(c.ID)
select c;

Linq .Count() from another table with inner join (C#)

So I have been trying to do this for a couple of hours by now but I still can't get it
Tables are like this.
**Questions**
- IDQuestion, IDSubject, DNI, others..
**Answers**
- IDQuestion , IDAnswer, DNICreator, others..
**StudentsPersonalinformation (just to get names, nothing related to the answers)**
- name, surname, DNI, others..
What i want to do is within the linq query get the amount of answers of a question. What I already have is this
var querySubjectQuestions = (from questions in db.questions
join studentspersonalinformation in db.studentspersonalinformation on questions.DNI equals studentspersonalinformation.DNI
where questions.IDSubject == IDSubject && questions.status == 1
select new
{
IDQuestion = questions.IDQuestion,
Title = questions.title,
Date = questions.date,
studentName = studentspersonalinformation.name,
studentSurname = studentspersonalinformation.surname,
}).OrderByDescending(c => c.Date);
But still don't know where to put the .Count from the other table where the IDQuestion equals the one it is querying.
Thanks :)
var querySubjectQuestions = (from questions in db.questions
join studentspersonalinformation in db.studentspersonalinformation on questions.DNI equals studentspersonalinformation.DNI
where questions.IDSubject == IDSubject && questions.status == 1
select new
{
IDQuestion = questions.IDQuestion,
Title = questions.title,
Date = questions.date,
studentName = studentspersonalinformation.name,
studentSurname = studentspersonalinformation.surname,
noAnswers = (from answer in db.answers
where answer.IDQuestion == questions.IDQuestion)
select answer).Count()
}).OrderByDescending(c => c.Date);
Without your c# entities of your DB tables, this is the best I can do.
select new
{
IDQuestion = questions.IDQuestion,
Title = questions.title,
Date = questions.date,
studentName = studentspersonalinformation.name,
studentSurname = studentspersonalinformation.surname,
noAnswer = questions.Answers.Count()
}

NHibernate LINQ Join 2 queries to retrieve stocks with 4 recent vendors

I have to retrieve stocks and recent 4 vendors. I got stock in one list. Got purchase order with vendors in another list. Want to get a merge result of all stocks with their recent 4 vendors in purchasing if any. I am not good with LINQ and this is NHibernate as well
This is my updated work. Seeking how to write third LINQ sql to get this.
IEnumerable<StockDetailReportModal> stockDetail = Session.Query<Stock>()
.Where(predicate)
.ToList()
.Select(n => new StockDetailReportModal
{
Id = n.Id,
Number = n.Number,
PaddedNumber = n.PaddedNumber,
Buyer = n.Buyer == null ? string.Empty : n.Buyer.FullName,
SalesTaxCode = n.SalesTaxCode == null ? null : n.SalesTaxCode.Code,
PurchasingUnitOfMeasure = n.PurchasingUnitOfMeasure,
InventoryUnitOfMeasure = n.InventoryUnitOfMeasure,
CatalogueDescription = n.CatalogueDescription,
BrandDescription = n.BrandDescription,
EconomicOrderQuantity = n.EconomicOrderQuantity,
LastYearPurchasePrice = n.LastYearPurchasePrice,
ThisYearIssuePrice = n.ThisYearIssuePrice,
NextYearIssuePrice = n.NextYearIssuePrice,
Description = n.StockCommodityCode == null ? string.Empty : n.StockCommodityCode.Code + "-" + n.StockCommodityCode.Description,
}).OrderBy(o => o.VendorNumber);
var vendorhistoryList = Session.Query<PurchaseOrderLineItem>()
.Where(pOpredicate)
.Where(p => p.Stock.Number != null)
.ToList()
.Select(c => new
{
stockId = c.Id,
LastPurchaseDate = c.PurchaseOrder.OrderDate.ToString("yyyy/MM/dd"),
VendorNumber = c.PurchaseOrder.PurchaseOrderVendor.Vendor.Number,
LastPurchasePrice = c.UnitPrice,
LastTransactionDate =
c.LastTransactionDate != null ? c.LastTransactionDate.Value.ToString("yyyy/MM/dd") : null,
LeadTimeDays = GetDays(c.PurchaseOrder.OrderDate, c.LastTransactionDate),
}).GroupBy(d => d.VendorNumber).Select(gpo => gpo
.OrderByDescending(x => x.LastPurchaseDate)
.Take(4));
My problem starts here when vendorhistoryList object does not show any property. What I am doing wrong here? I am trying to left join stockDetail with vendorhistoryList on stock.id with 1 or more stock rows with upto 4 recent vendors. Please suggest what should I do?
Here is the last part I need.
var stockdetailResult = from sd in stockDetail
join vh in vendorhistoryList on sd.Id equals vh.Id into sv
from vs in sv.DefaultIfEmpty() ???
.select ( c=> c.fields1....c.fields2...)
This was a very similar problem I was facing so just answered to that question which can be applied here as well. Attaching a link of that question.
Product with last 4 vendors on transaction date

LINQ to Entities extensions; multiple subqueries, joins and case statements

I have googled thoroughly for examples to my latest LINQ endeavor ("Hi, I'm new to LINQ"). I'll spare you the list of pages I've visited.
Here is sample SQL of what I would like to achieve:
use myDB;
go
declare #requestedDay datetime = convert(datetime, (convert(varchar(10), getdate(), 101)), 101)
declare #type1 int = 20
;with currentQuery as ( select
case when z.someID = #type1 and bet.someValue is null then 1
else 0 end as count1,
case when z.someID = #type1 and bet.someValue = alef.otherID then 1
else 0 end as count2,
from dbo.Work as dalet
left join dbo.Workers as z on alef.workerAssignedID = z.ID
left join dbo.Contracts as alef on alef.workOrderID = gimel.ID
left join dbo.Subcontracts as bet on alef.WorkOrderID = alef.WorkOrderID
and alef.WorkerAssignedID = dalet.WorkerID
where convert(varchar(10),alef.dateTimeofWork,101) = #requestedDay),
futureQuery as ( select
case when gimel.text_EN like '%blah%' and bet.someValue is null then 1
else 0 end as count3,
case z.someID = #type1 and bet.someValue = alef.otherID then 1
else 0 end as count4,
from dbo.Work as dalet
left join dbo.Workers as z on dalet.workerAssignedID = z.ID
left join dbo.Contracts as alef on dalet.workOrderID = alef.ID
left join dbo.Subcontracts as bet on dalet.WorkOrderID = bet.WorkOrderID and wa.WorkerAssignedID = wr.WorkerID
left join dbo.Lookups as gimel on dalet.skillID = gimel.ID
where convert(datetime,(convert(varchar(10),alef.dateTimeofWork,101)),101) > #requestedDay)
select sum(count1) as prop1name, sum(count2) as prop2name,
sum(count3) as prop3name, sum(count4) as prop4name
from currentQuery, futureQuery
This is, of course, a shortened version of a much larger query. It contains just the basics of what I need. The names may be confusing but I was looking for something unique. They also match their LINQ cousins below.
...that said, here is where I am stuck: ("What I have tried so far:") I've included some comments that describe problems I am trying to think through.
//snip injection stuff above
public IQueryable<DailyCasaLatinaReport> DailyCasaLatina(DateTime dateRequested)
{
IQueryable<DailyCasaLatinaReport> query;
var daletQ = waRepo.GetAllQ();
var zQ = zRepo.GetAllQ();
var alefQ = alefRepo.GetAllQ();
var betQ = betRepo.GetAllQ();
var gimelQ = gimelRepo.GetAllQ();
int type1 = 20;
int type2 = 21;
query = daletQ
.GroupJoin(gimelQ, dalet => dalet.skillID, look => look.ID,
(dalet, look) => new
{
dalet,
enSkillText = look.FirstOrDefault().text_EN
}) //currently envisioning a left outer join of
//all .skillID, with English text available
//for column and condition matches from the
//next three joins.
.GroupJoin(betQ, gimel => gimel.dalet.workOrderID, wr => wr.WorkOrderID,
(gimel, wr) => new
{
gimel,
reqWorkerID = wr.FirstOrDefault().WorkerID,
reqOrderID = wr.FirstOrDefault().WorkOrderID
}) //now envisioning a join on the original table
//where any match in workerID is joined. THIS
//IS A PROBLEM, I actually need to join on two
//conditions to avoid duplicates.
.GroupJoin(alefQ, bet => bet.gimel.dalet.workOrderID, wo => wo.ID,
(bet, wo) => new
{
bet,
timeOfWork = wo.FirstOrDefault().dateTimeofWork
}) //now envisioning yet another join where the
//dateTimeofWork property from woQ is stamped
//onto all matches of woQ's ID column. since
//woQ.ID is the common point of reference for
//like, everything, there should be no nulls.
.GroupJoin(zQ, alef => alef.bet.gimel.dalet.workerAssignedID, w => w.ID,
(alef, w) => new
{
alef,
listDWC = alef.bet.someValue == 0 ? (w.FirstOrDefault().someID == type1 ? 1 : 0) : 0,
propioDWC = alef.bet.someValue == alef.bet.gimel.dalet.workerAssignedID ?
(w.FirstOrDefault().someID == type1 ? 1 : 0) : 0,
})
// here I'm stuck because there's no way to do
//the future conditions, i.e., what would be my
//second subquery
.Where(x => x.alef.timeOfWork == dateRequested)
.GroupBy(y => y.alef.bet.gimel.dalet.ID)
.Select(group => new dailyReport
{
count1 = group.Sum(z => z.listDWC),
count2 = group.Sum(z => z.propioDWC),
count3 = //???
count4 = //???
});
return query;
}
//snip class definition below
So, sorry for the long question (though I've seen longer), but any ideas about how to squeeze my second subquery in here would be helpful. I don't know LINQ that well and honestly don't know if I can put a separate .Where clause and/or second .Select clause. One thing to note is that dailyReport is a defined class and must have (in our example) count1 thru count4 defined.
Appreciate any help,
Chaim
Based on comments it was determined that breaking up this monster sql query would be more beneficial to the maintainability of his code and a new question will be created if needed.

Is there an alternative to LINQ let operator that doesn't hit performance? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I have a LINQ to Entity query which uses a select to transform raw data from the db into an object, performing some calculations in the process. The calculations are repeated a couple of times so I tried refactoring the LINQ to make use of a let. However, in doing so, performance is hit drastically. Is there an alternative to LET which I can use just for code re-usability without affecting performance?
var defaultHours = 40;
var defaultOldPersonPoints = 100;
var defaultYoungPersonPoints = 50;
// Example with no let but lots of ugly, unreadable, redundant code
var exampleNoLet =
(from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
select new
{
AllocatedPoints = (p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0)
+ (int)(
(p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0)
* (p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0))
});
// Using the LET allows me to clean up the code somewhat but causes a massive performance hit
var exampleUsingLet =
(from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
let defaultPoints = p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0
let contractedHourRatio = p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0
select new
{
AllocatedPoints = defaultPoints + (int)(defaultPoints * contractedHourRatio)
});
If the query performance is the problem, then consider moving that to LINQ-to-Objects. For example, at the moment, you aren't using anything other than p in the projection (it is not clear to me why you are doing what appears to be a left-outer-join, in fact), so you could just do something like:
var queryBase = from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
select p;
var query = from p in queryBase.AsEnumerable() // <=== switch to LINQ-to-Objects
let defaultPoints = p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0
let contractedHourRatio = p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0
select new
{
AllocatedPoints = defaultPoints + (int)(defaultPoints * contractedHourRatio)
});
Here, the SQL query should be pretty simple; all the more complex work is done in LINQ-to-Objects.

Categories

Resources