I'm getting a problem with a query with linq in EF.
Basically, what i'm tring to do is this, in plain SQL:
SELECT
t2.*
FROM
[SHP_Console2].[dbo].[Domain] t1
INNER JOIN
[SHP_Console2].[dbo].[Domain] t2
ON t2.[left] >=t1.[left] AND t2.[right]<=t1.[right]
WHERE
t1.ID =1
I'm not able to do this with linq.
I'm tring this:
from a in DomainRep.Where(c => c.ID == domainID).Select(c => new { c.left, c.right })
from b in DomainRep.Where(x => x.left >= a.left && x.right <= a.right)
select a;
What i'm doing wrong?
You mixed your query with anonymous types. You can't do that this way.
You also can't use JOIN with >= condition - LINQ does not support that kind of statements. However, it can be done using alternative syntax.
from a in DomainRep
from b in DomainRep
where b.left >= 1.left && b.right <= a.right && a.ID = 1
select b;
Edit: Reference: http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/428c9db2-29f6-45d8-ab97-f00282397368/
var query = (from a in DomainRep
from b in DomainRep
where a.left >= b.left
select b)
.ToList();
Related
I want to have Linq Query as below, but the not able to, its giving me compile time error any help please? The error is "inference failed to call the Join" - any help please? I want to use join within where clause of other query, is that possible?
Case _case = (from x in this.Context().CaseRepository.GetAll()
where (from g in x.Violations
join a in this.Context().OneToManyRepository.GetAll().Where(a => a.ParentEntity == "Notice" && a.ChildEntity == "Violation")
on new { g.ViolationId, this.NOVId } equals new { a.ChildEntityId, a.ParentId }
where g.CaseId == x.CaseId
select g).Count() > 0
select x).FirstOrDefault();
this.TriggerMetaDataUpdate<Case>(_case);
this.TriggerMetaDataUpdate<InspectionResult>(this.InspectionResult);
I did it in the following way:
var Violations = (from v in UnitOfWork.ViolationRepository.GetAll()
join a in UnitOfWork.OneToManyRepository.GetAll().Where(a => a.ParentEntity == "Notice" && a.ChildEntity == "Violation")
on v.ViolationId equals a.ChildEntityId
join b in UnitOfWork.OneToManyRepository.GetAll().Where(a => a.ParentEntity == "Notice" && a.ChildEntity == "Case")
on a.ParentId equals b.ParentId
where b.ChildEntityId == caseId
orderby v.ViolationId
select v).ToList();
I am reasonably new to Linq and it seems quite easy to iuse but I am having an issue when trying to extract a value from a table that is linked/constrained by 3 other tables.
I have this in my SQL DB:
I am using Asp.Net 4 and Entity Framework 6.
I have as a parameter the 'DatabaseName'.
I ultimately want to get the SubscriptionRef that is assigned to this name.
I could do this step-by-step (ie using multiple linqs) but I thought it would look 'clean' using just 1 linq statment.
I have got as far as this:
var names = o.RegisteredNames.Where(d => d.DatabaseName == DBName).Where(d => d.ClientNames.Where(f => f.ClientId == f.Client.ClientId).FirstOrDefault();
But I get the error:
Cannot implicitly convert type 'Services.ClientName' to 'bool'
You have a Problem here:
d => d.ClientNames.Where(f => f.ClientId == f.Client.ClientId)
f => ... returns a single ClientName or null, which causes your error, because there should be a boolean.
If you want this first value or null, you should replace
.Where(d => d.ClientNames ...
//with
.Select(d => d.ClientNames ...
Try this:
o.RegisteredNames.First(d => d.DatabaseName == DBName).ClientNames.Select(x=>x.Client.Subscription.SubscriptionRef)
It should give you list go SubscriptionRef.
You can try with one LINQ query like...
var names = o.RegisteredNames.Where(d => d.DatabaseName == DBName ).FirstOrDefault();
You might wanna try sql style:
var client = from c in db.Clients
join cn in db.ClientNames on c.ClientId equals cn.ClientId
join rn in db.RegisteredNames on cn.RegisteredNamesId equals rn.RegisteredNameId
where rn.DatabaseName == "YourDBName"
select c;
But it also depends on how your objects were built.
Try using join:
var names = (
from names in o.RegisteredNames.Where(d => d.DatabaseName == DBName)
join cnames in o.ClientNames on names.RegisteredNamesId equals cnames.RegisteredNamesId
select cnames.ClientId
).FirstOrDefault();
Add as many joins as you want.
Try this
It works in List,
var option1= o.RegisteredNames
.Where(g => g.DbName == "YourDbName")
.Where(h => h.ClientNames.Any(f => f == 5))
.FirstOrDefault();
var option2= o.RegisteredNames
.FirstOrDefault(h => h.DbName == "Name" && h.ClientNames.Any(j => j == 1));
How i can obtain the similar Linq query as this SQL query using Linq method based?
SELECT * FROM F_ARTICLE A
LEFT JOIN F_ARTFOURNISS AF ON AF.AR_Ref = A.AR_Ref AND AF.AF_Principal = 1
ORDER BY A.AR_Design DESC
OFFSET 500 ROWS FETCH NEXT 100 ROWS ONLY
I'm using method based due to System.Linq.Dynamic requirements.
The mapping is like this:
I started by this but i don't know how to limit to AF_Principal = 1:
var query = context.F_ARTICLE
.Join(
context.F_ARTFOURNISS,
a => a.AR_Ref,
t => t.AR_Ref,
(a, t) => new { a, t })
.Select(
z => new ArticleItem()
{
Article = z.a,
Tarif = z.t.FirstOrDefault()
})
.OrderBy($"{field} {direction}");
return query.Skip(startIndex).Take(count).ToList();
The code is from my head but the point is using DefaultIfEmpty for doing LEFT JOIN:
var query = from farticle in context.F_ARTICLE
join b in context.F_ARTFOURNISS
on new {farticle.AR_Ref, AF_Principal = 1} equals new {b.AR_Ref, b.AF_Principal} into gj
from subres in gj.DefaultIfEmpty()
select farticle;
return query.Skip(startIndex).Take(count).ToList();
Also you can limit by AF_Principal using Where clause (I think DBMS engine will optimize the query anyway)
see if this works
var query = from F1 in context.F_ARTICLE join F2 in context.F_ARTFOURNISS
on F1.AR_Ref equals F2.AR_Ref into newF
from F3 in newF.where(f=>f.AF_Principal == 1).DefaultIfEmpty()
select f;
return query.Skip(startIndex).Take(count).ToList();
I think i found the query:
var query = context.F_ARTICLE
.GroupJoin(
context.F_ARTFOURNISS,
a => a.AR_Ref,
t => t.AR_Ref,
(a, t) => new { a, t })
.Select(
z => new ArticleItem()
{
Article = z.a,
Tarif = z.t.Where(t=>t.AF_Principal == 1).FirstOrDefault()
})
.OrderBy($"{field} {direction}");
return query.Skip(startIndex).Take(count).ToList();
I am creating a LINQ statement like following
from c2 in context.AspNetRoles
join c1 in context.RoleActions
on c2.Id equals c1.RoleId
where c2.UserId == System.Web.HttpContext.Current.User.Identity.GetUserId()
select new { c2.Name };
Notice that c2 appears first. The problem is the
c2.UserId
is not showing in intelligence. Is this a common behavior in LINQ. how can I fix the above LINQ statement, order is important?In where clause with join should have table identifier in the last in joining?
Thanks
If i understand you well...
You can mix standard notation of query with lambda. So, if you want to filter context.AspNetRoles then join context.RoleAction, you can try something like that:
var result = from c2 in context.AspNetRoles.Where(x=>x.Field=="SomeValue"
&& x.UserId == System.Web.HttpContext.Current.User.Identity.GetUserId())
join c1 in context.RoleActions on c2.Id equals c1.RoleId
select new { c2.Name };
Why join if you need only one value? Maybe try something like this:
var result = context.AspNetRoles
.Where(o => context.RoleActions.Any(oo => oo.RoleId == o.Id) &&
o.UserId == System.Web.HttpContext.Current.User.Identity.GetUserId())
.Select(o => o.Name)
.ToList();
I was wandering if someone can explain to me why this query doesn't act like the SQL Left join, I cant seem to work out why. I have been doing a bit of hunting and I can't seem to work it out. As far as I can tell it should.
I.e. In a table with 5 Active Customers it will only return 2 of those Customers instead of all 5; 2 with values and 3 with either null or 0?
var results = from c in DataContext.Customers
where c.Active
join j1 in
(from i in DataContext.Invoice where i.State== "Pending" &&
i.InvoiceDate.Date >= From.Date && i.InvoiceDate.Date <= To.Date
group i by i.Customer into x
select new { x.Key, Total = x.Count() }) on a equals j1.Key
select new { c, j1.Total };
Thanks
By using DefaultIfEmpty() method you can do it.
Try this code
i have implementd your problem's solution
revert me if it worked
var results = from c in DataContext.Customers
where c.Active
join j1 in
(from i in DataContext.Invoice where i.State== "Pending" &&
i.InvoiceDate.Date >= From.Date && i.InvoiceDate.Date <= To.Date
group i by i.Customer into x
select new { x.Key, Total = x.Count() }) on a equals j1.Key into j3
from k in j3.DefaultIfEmpty()
select new { c, k.Total };
I would try DefaultIfEmpty() method on your j1 subquery, because you aren't allowing the query to join on null values.
See the similar question for examples.