Left join Entity framework 5.0.0 not using LINQ - c#

I've created this with LINQ
var main = (from p in participants
from cc in participants
where cc.Id != p.Id
select new { Id1 = p.Id, Id2 = cc.Id });
I was able to recreate it to..
var main = participants.SelectMany(n => participants, (x, y) => new { Id1 = x.Id, Id2 = y.Id })
.Where(x => x.Id1 != x.Id2).ToList();
Same think I want to do with...
var test = (from m in main
join cr in db.ContactRelations on new { Id1 = m.Id1, Id2 = m.Id2 } equals new { Id1 = cr.ContactId, Id2 = cr.RelationContactId } into tt
from cr in tt.DefaultIfEmpty()
select new { m.Id1, m.Id2, found = cr == null ? false : true }).ToList();
So far, It's not left join but only join.. and that null values is what I need..
var test = main.Join(db.ContactRelations,
c => new { Id1 = c.Id1, Id2 = c.Id2 },
x => new { Id1 = x.ContactId, Id2 = x.RelationContactId },
(c, x) => new { c.Id1, c.Id2, found = x == null ? false : true }).ToList();
Is possible to implement DeafultIfEmpty() somehow ?
Thanks..

Related

Yet another “A query body must end with a select clause or a group clause”

This query does work, but I am trying to combine the two steps into one query.
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
.Where
(u =>
u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office)
)
select new
{
hOffice = o.Name,
bName = u.Name
};
var query2 = query1.GroupBy(t => new { office = t.hOffice, name = t.bName })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() });
If I try to combine the two queries using the following query it gives me the “A query body must end with a select clause or a group clause” error.
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
.Where
(u =>
u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office)
)
.GroupBy(t => new { office = t.Office, name = t.Name })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() });
I think I have to add a select something, but I can't figure out what.
Can anyone please help?
Your query must contain a select clause. The .Where(...).GroupBy(...).Select(...) are only on the db.GetTable<Users>(). Something like:
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>().Where(u => u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office))
.GroupBy(t => new { office = t.Office, name = t.Name })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() })
select new { /* Desired properties */};
But I think you are looking for something like:
var result = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
where u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office))
group 1 by new { t.Office, t.Name } into g
select new { Office = g.Key.Office, Name = g.Key.Name, Count = g.Count() };

Execute query using LINQ or EF to fetch records from multiple tables

I've been searching for a while now. But all the solutions seems to be different than what I expect.
So this is my query in SQL:-
Select * from
(
select Name,Description Descr from CourseTbl
union all
select MainDesc Name,MainDesc Descr from CoursedescTbl
union all
select SubHeading Name,SubDesc Descr from CourseSubDesc
union all
select Name,Descr as Descr from InternTbl
)A where A.Name like '%D%' or A.Descr like '%D%'
I want to execute the above query using LINQ or EF. and return the list in Json format. So I tried many failed attempts and this is one of them:-
public JsonResult SearchDetail()
{
string SearchKey = Request.Form["SearchName"].ToString();
IEnumerable<SearchList> QueryResult;
using (EBContext db = new EBContext())
{
try
{
QueryResult =
(from x in db.Courses
select new { A = x.Name, B = x.Description })
.Concat(from y in db.CourseDesc
select new { A = y.MainHeading, B = y.MainDesc })
.Concat(from z in db.CourseSubDesc
select new { A = z.SubDesc, B = z.SubHeading })
.Concat(from w in db.Interns
select new { A = w.Name, B = w.Descr })
.ToList();
}
catch (Exception ex)
{
return new JsonResult
{
Data = ex.Message,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
return new JsonResult
{
Data = QueryResult,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
And my SearchList Class is like this:-
public class SearchList
{
public string Name { get; set; }
public string Descr { get; set; }
}
I'm not able to put the where clause in linq query which will search in all table.
I'm getting error when I assign queryresult to my ef query. It says cannot cast to Innumerable.
Thanks in Advance.
Could you explain more on the error you are getting?
Also, have you tried using .Union() in linq?
QueryResult = db.Courses.Select(x=> new { A = x.Name, B= x.Description})
.Union(db.CourseDesc.Select(y=> new {A = y.MainHeading, B = y.MainDesc })
.Union( //so on
.ToList(); //this isn't necessary
Edit: There are two ways to input where clause, either with each search, or at the end:
QueryResult = db.Courses.Where(x=>x.Name == "Name").Select(x=> new { A = x.Name, B= x.Description})
.Union(db.CourseDesc.Where(y=>y.MainHeading == "Name").Select(y=> new {A = y.MainHeading, B = y.MainDesc })
.Union( //so on
.ToList();
Or:
QueryResult = db.Courses.Where(x=>x.Name == "Name").Select(x=> new { A = x.Name, B= x.Description})
.Union(db.CourseDesc.Where(y=>y.MainHeading == "Name").Select(y=> new {A = y.MainHeading, B = y.MainDesc })
.Union( //so on
//Where can go either before or after .ToList
.Where(item=>item.A == "Name")
.ToList();
You did not say what error/exception you are getting. But your QueryResult is of type IEnumerable<SearchList> and you appear to be assigning it an enumerable of anonymous type { A, B }.
Try this:
QueryResult = (from x in db.Courses
select new SearchList { Name = x.Name, Descr = x.Description })
.Concat(...)
.ToList();
Or
QueryResult = db.Courses.Select(x => new SearchList
{ Name = x.Name, Descr = x.Description})
.Concat(...)
.ToList();
UPDATE
Your #2 issue will be fixed if you changed your select to new up a SearchList as I did above, instead of new-ing an anonymous type.
As for your issue #1, you should insert the Where() before your Select():
result1 = db.Courses
.Where(x => x.Name.Contains('D') || x.Description.Contains('D'))
.Select(x => new SearchList { Name = x.Name, Descr = x.Description});
result2 = db.CourseDesc
.Where(y => y.MainHeading.Contains('D') || y.MainDesc.Contains('D'))
.Select(y => new SearchList { Name = y.MainHeading, Descr = y.MainDesc});
result3 = db.CourseSubDesc
.Where(...)
.Select(...);
QueryResult = result1.Concat(result2).Concat(result3).ToList();
Doing Where() as part of the query on each table is important so you do not fetch all records from that table, unlike if you do the Where() after Concat(). Also note that Concat() may throw an ArgumentNullException.
Take the lists Separately and query and concat
check this example
List<string> a = new List<string>() { "a", "b", "c" };
List<string> b = new List<string>() { "ab", "bb", "cb" };
IEnumerable<SearchList> QueryResult =
a.Where(x => x.Contains("a")).Select(x => new SearchList() { Name = x, Descr = x })
.Concat(b.Where(x => x.Contains("a")).Select(x => new SearchList() { Name = x, Descr = x }));

Group By Query with Entity Framework Query Method

i have this query and i wanna to change to linq query methods:
select o.OrderID,o.OrderNo, o.OrderDate, SUM(TotalAmount) Total
from orders o inner join
OrderDetails e on o.OrderID=e.OrderID
group by o.OrderNo, o.OrderDate,o.OrderID order by o.OrderNo desc
i have been trying the follow:
public List<Orders>List()
{
var list = new List<Orders>();
try
{
using (var db = new MyDatabaseEntities())
{
list = db.Orders.Select(o => new { o.OrderID, o.OrderNo, o.OrderDate, o.OrderDetails.TotalAmount}).
GroupBy(x => new { x.OrderID, x.OrderNo, x.OrderDate }).
Select(o => new
{
o.Key,
id = o.OrderID,
order = o.NumOrder,
date = o.OrderDate,
Total = o.Sum(o.TotalAmount)
}).Tolist();
}
}
catch(Exception e)
{
throw new Exception(e.Message);
}
return list;
}
Someone can Help me?
I think try this:
var list=db.Orders.Join(OrderDetails,
o=>o.OrderID
e=>e.OrderID
(o,e)=>new{Orders=o,OrderDetails=e})
.GroupBy(o=>new {o.OrderNo, o.OrderDate,o.OrderID})
.OrderBy(x=>x.Key.OrderNo)
.Select(o=>new{
o.Key.OrderID,
o.Key.OrderNo,
o.Key.OrderDate,
Total=o.SUM(x=>x.TotalAmount)})
.ToList();
Try this :
Sql like syntax
from t in TblOrders
join d in TblOrderDetails
on t.Id equals d.OrderId
group d by new {t.Id, t.OrderNo, t.OrderDate} into g
orderby g.Key.OrderNo descending
select new
{
ID = g.Key.Id,
OrderNo = g.Key.OrderNo,
OrderDate = g.Key.OrderDate,
amount = g.Sum(x=>x.Rate)
}
lambda like:
TblOrders
.Join (
TblOrderDetails,
t => t.Id,
d => d.OrderId,
(t, d) =>
new
{
t = t,
d = d
}
)
.GroupBy (
temp0 =>
new
{
Id = temp0.t.Id,
OrderNo = temp0.t.OrderNo,
OrderDate = temp0.t.OrderDate
},
temp0 => temp0.d
)
.OrderByDescending (g => g.Key.OrderNo)
.Select (
g =>
new
{
ID = g.Key.Id,
OrderNo = g.Key.OrderNo,
OrderDate = g.Key.OrderDate,
amount = g.Sum (x => x.Rate)
}
)

LINQ pivot top 5 rows to columns

The desired output is a set of rows containing details about a physician and the top 5 procedures they performed (by volume) that are not in our benchmarking tables - with a minimum of one per month. Even with my limited LINQ experience, I have managed to get this working, but the performance in abysmal. In the spirit of becoming better at LINQ, I thought I'd see if there was a better way to approach this (besides coding in SQL).
Here is the entire method, although I believe it is the final statement (var report =) that deserves the most attention.
//Get the Providers for the selected AccessLevel & Report Period
var providerRiskLevels = GetProviderRiskLevelForAccessLevel(userAccessLevelId, reportPeriodId, providerNamePiece);
short benchmarkYear = (
from rp in db.ReportPeriods
where rp.ReportPeriodId == reportPeriodId
select rp.BenchmarkDataYear
).FirstOrDefault();
byte Duration = (
from rp in db.ReportPeriods
where rp.ReportPeriodId == reportPeriodId
select rp.Duration
).FirstOrDefault();
//Summarize counts by procedure code (ignoring modifiers)
var codeCounts =
from pp in db.ProviderProductions
//332 - restrict to valid codes
join pc in db.ProcedureCodes on pp.ProcedureCode equals pc.ProcedureCode1
where pp.ReportPeriodId == reportPeriodId
//show deleted codes as potential issue
&& pc.TerminatedDate == null
&& (codeFilter == null || pp.ProcedureCode == codeFilter)
join pc in db.PspsProcedures
on new { col1 = pp.ProcedureCode, col2 = benchmarkYear } equals new { col1 = pc.ProcedureCode, col2 = pc.Year } into left
from l_d in left.DefaultIfEmpty()
where l_d == null
group pp by
new { pp.ProviderId, pp.ProcedureCode }
into g
orderby g.Key.ProviderId, g.Sum(x => x.Volume) descending
where g.Sum(x => x.Volume) > Duration
select new NewCodesEntity
{
ProviderId = g.Key.ProviderId,
ProcedureCode = g.Key.ProcedureCode,
Volume = g.Sum(x => x.Volume)
};
//Get top 5 procedures performed by provider
var newCodes =
from cc in codeCounts
group cc by
new { cc.ProviderId }
into g
select new ProviderNewCodesEntity
{
ProviderId = g.Key.ProviderId,
Codes = g.OrderByDescending(x => x.Volume).Take(5).ToList()
};
//Build the report
var report =
from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
&& (filterRiskLevelNums.Contains(pr.RiskLevelNum))
&& (filterSpecialtyId == 0 || pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new ProbeAuditEntity
{
ProviderId = pr.Provider.ProviderId,
ProviderName = pr.Provider.Name,
ProviderCode = pr.Provider.ProviderCode,
SpecialtyName = pr.Provider.Specialty.Name,
SpecialtyCode = pr.Provider.Specialty.SpecialtyCode,
VisibleRisk = pr.RiskScore,
NewCode1 = nc.Codes.OrderByDescending(c => c.Volume).FirstOrDefault().ProcedureCode,
NewCode2 = nc.Codes.OrderByDescending(c => c.Volume).Skip(1).FirstOrDefault().ProcedureCode,
NewCode3 = nc.Codes.OrderByDescending(c => c.Volume).Skip(2).FirstOrDefault().ProcedureCode,
NewCode4 = nc.Codes.OrderByDescending(c => c.Volume).Skip(3).FirstOrDefault().ProcedureCode,
NewCode5 = nc.Codes.OrderByDescending(c => c.Volume).Skip(4).FirstOrDefault().ProcedureCode
};
return report;
I appreciate your suggestions.
Give this a try for the report:
//Build the report
var report =
(from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
&& filterRiskLevelNums.Contains(pr.RiskLevelNum)
&& (filterSpecialtyId == 0
|| pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new
{
RiskLevel = pr,
NewCodes = nc.Codes.OrderByDescending(c => c.Volumn).Select(c => c.ProcedureCode).Take(5)
})
.AsEnumerable()
.Select(x => new ProbeAuditEntity
{
ProviderId = x.RiskLevel.Provider.ProviderId,
ProviderName = x.RiskLevel.Provider.Name,
ProviderCode = x.RiskLevel.Provider.ProviderCode,
SpecialtyName = x.RiskLevel.Provider.Specialty.Name,
SpecialtyCode = x.RiskLevel.Provider.Specialty.SpecialtyCode,
VisibleRisk = x.RiskLevel.RiskScore,
NewCodes = x.NewCodes.Concat(Enumerable.Repeat(<DefaultProcedureCodeHere>, 5)).Take(5)
});
Or, if ProbeAuditEntity is a class you could do this:
//Build the report
var report =
(from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
&& filterRiskLevelNums.Contains(pr.RiskLevelNum)
&& (filterSpecialtyId == 0
|| pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new ProbeAuditEntity
{
ProviderId = x.RiskLevel.Provider.ProviderId,
ProviderName = x.RiskLevel.Provider.Name,
ProviderCode = x.RiskLevel.Provider.ProviderCode,
SpecialtyName = x.RiskLevel.Provider.Specialty.Name,
SpecialtyCode = x.RiskLevel.Provider.Specialty.SpecialtyCode,
VisibleRisk = x.RiskLevel.RiskScore,
NewCodes = nc.Codes.OrderByDescending(c => c.Volumn).Select(c => c.ProcedureCode).Take(5)
})
.ToList();
report
.ForEach(x => x.NewCodes = x.NewCodes.Concat(Enumerable.Repeat(<DefaultProcedureCodeHere>, 5)).Take(5);

Join LINQ with a List<> in select new

hi first time im asking here so il try to do it correctly
i have a problem im making a shopping basket and im nearly there but always a but
what i want to have is something like this
List<HKurv> KurvInnhold = (List<HKurv>)Session["KurvInnhold"];
DataClasses1DataContext db = new DataClasses1DataContext();
if (Session["KurvInnhold"] != null)
{
var query = from a in db.Cabinets
from b in db.Commodities
from e in db.sArticleNumbers
from d in KurvInnhold
where
d.VareKjøpt.Contains(e.ArtNum) &&
a.ArticleNumberID == e.ID &&
a.ArticleNumberID == b.ArticleNumberID
select new
{
BestiltAntall = d.AntallValgt,
Price = b.Price,
ModelName = a.ModelName,
};
Handlekurv1.DataSource = query;
Handlekurv1.DataBind();
}
But it does not allow for usage of db and list<> in same query
Solved! Modified magnus's answer
var kjopKollonne = from p in KurvInnhold
select p.VareKjøpt;
var query1 = (from a in db.Cabinets
from b in db.Commodities
from e in db.sArticleNumbers
where
kjopKollonne.Contains(e.ArtNum) &&
a.ArticleNumberID == e.ID &&
a.ArticleNumberID == b.ArticleNumberID
select new
{
ArtNum = e.ArtNum,
Price = b.Price,
ModelName = a.ModelName,
}).ToList();
var query2 = from a in query1
join b in KurvInnhold on a.ArtNum equals b.VareKjøpt
select new
{
BestiltAntall = b.AntallValgt,
Price = a.Price,
ModelName = a.ModelName,
};
Handlekurv1.DataSource = query2;
Handlekurv1.DataBind();
Try this:
var query1 = from a in db.Cabinets
from b in db.Commodities
from e in db.sArticleNumbers
from d in KurvInnhold
where
KurvInnhold.Select(k => k.VareKjøpt).Contains(e.ArtNum) &&
a.ArticleNumberID == e.ID &&
a.ArticleNumberID == b.ArticleNumberID
select new
{
ArtNum = e.ArtNum,
Price = b.Price,
ModelName = a.ModelName,
}.ToList();
var query2 =
from a in query1
join b in KurvInnhold on a.ArtNum equals b.VareKjøpt
select new
{
BestiltAntall = b.AntallValgt,
Price = a.Price,
ModelName = a.ModelName,
};
Handlekurv1.DataSource = query2;
Handlekurv1.DataBind();

Categories