var query2 = (from tc in Entities.TutorCourses
join c
in Entities.Course
on tc.CourseId equals c.Id
where tc.CourseId == id
select tc.Username).ToList();
var query1 = Entities.User
.Select(u => u.Role
.Select(p => p.Name)
.Contains("Tutor"));
I am trying to return all the Users from a database that are in query1 except all those Users that are in query2 as above.
How can I achieve this? I tried using returning query1 by adding .Except(query2); in the end but I am not sure which is the best method to implement a 'NOT IN' function in LINQ
That 2nd query just looks wrong. Try this:
var query2 = (from tc in Entities.TutorCourses
join c
in Entities.Course
on tc.CourseId equals c.Id
where tc.CourseId == id
select tc.Username).ToList();
var query1 = Entities.User
.Where(u =>
query1.Any(un => un != u.Username) &&
u.Role.Name.Contains("Tutor"))
.Select(u => u.Role);
If this all query are the same type try to you this method
Intersect
You can use the Any to find matches between two lists, then add a ! to specify that you want the ones that don't match. Here's an example that should work for you:
var excludedList = query1.Where(x => !query2.Any(y => y.Id == x.Id));
How about query1.Where(c=> !query2.Contains(c));
Related
Query returns f.File field but need to return related with f.File field c.Name field also .
How to get f.File and c.Name related fields as a result of the query where result is distinted by f.File field?
var query = from f in db.FileCommits
join c in db.Commits
on f.CommitID equals c.Id
where (c.WorkspaceId == workspaceId && f.CommitID <= commitId)
select new{f, c};
var listOfFiles = query
.OrderByDescending(p => p.c.Id)
.Select(f => f.f.File)
.Distinct()
.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));
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();
This is the SQL code the produces the correct results:
select s.Code, s.Name, coalesce(ss.Url, a.Url), a.SocialMediaTypeKey
from School s
Left join
(
SELECT dbo.SchoolSocialMedia.SocialMediaTypeKey
, SchoolSocialMedia.Url
, dbo.Department.Name
, dbo.Department.ImportBusinessKey
FROM dbo.SchoolSocialMedia
INNER JOIN dbo.Department ON dbo.SchoolSocialMedia.DepartmentId = dbo.Department.Id
) A
ON 1 = 1
Left join dbo.SchoolSocialMedia ss ON ss.SchoolId = s.Id and ss.SocialMediaTypeKey = a.SocialMediaTypeKey
where s.[DeactivatedDate] is null
This is how far I have gotten in C#, but it is not producing the correct results--in fact, it is returning zero results:
var departmentSocialMediaResult =
from ssm in context.SchoolSocialMedia
from d in context.Department.Where(d => d.Id == ssm.DepartmentId)
select new { ssm.SocialMediaTypeKey,
ssm.Url,
d.Name,
ssm.SchoolId };
var result =
(from s in context.School
from ssm in context.SchoolSocialMedia.DefaultIfEmpty()
from dssm in departmentSocialMediaResult.DefaultIfEmpty()
.Where(dssm => dssm.SchoolId == s.Id && dssm.SocialMediaTypeKey == ssm.SocialMediaTypeKey)
select new { ssm.SchoolId, ssm.SocialMediaTypeKey, ssm.Url })
.ToDictionary(ssm => new SchoolSocialMediaKey(
ssm.SchoolId, ssm.SocialMediaTypeKey),
ssm => ssm.Url);
Does anyone have any suggestions on how to better convert the T-SQL to LINQ to Entities? What am I doing wrong? TIA.
UPDATE:
Thank you, #Aducci, your response is the correct answer. Since the result is being put into a dictionary, this is what I ended up using:
var query =
(from s in context.School
from a in
(
from ssm in context.SchoolSocialMedia
join d in context.Department on ssm.DepartmentId equals d.Id
select new
{
ssm.SocialMediaTypeKey,
ssm.Url,
d.Name
}
).DefaultIfEmpty()
from ss in context.SchoolSocialMedia
.Where(x => s.Id == x.SchoolId)
.Where(x => a.SocialMediaTypeKey == x.SocialMediaTypeKey)
.DefaultIfEmpty()
select new
{
ss.SchoolId,
Url = ss.Url ?? a.Url,
a.SocialMediaTypeKey
}).Distinct();
return
query
.ToDictionary(
ssm => new SchoolSocialMediaKey(
ssm.SchoolId, ssm.SocialMediaTypeKey),
ssm => ssm.Url);
I am sure there is a better way to write the original query, but instead of spending too much time analyzing I just translated it into linq. In general, your linq query should have the same structure as the tsql query like this:
var query =
from s in context.School
from a in
(
from ssm in context.SchoolSocialMedia
join d in context.Department on ssm.DepartmentId equals d.Id
select new
{
ssm.SocialMediaTypeKey,
ssm.Url,
d.Name,
d.ImportBusinessKey
}
).DefaultIfEmpty()
from ss in context.SchoolSocialMedia
.Where(x => s.Id == x.SchoolId)
.Where(x => a.SocialMediaTypeKey == x.SocialMediaTypeKey)
.DefaultIfEmpty()
select new
{
s.Code,
s.Name,
Url = ss.Url ?? a.Url,
a.SocialMediaTypeKey
};
var c = from p in db.Testings
where p.id == Convert.ToInt32(k)
select new{p.ItemId};`
The above Linq is returning multiple amount of rows containing different ItemIds.
Now, I am trying to retrieve all the rows from Questions table containing all those ItemIds I got returned in the above linq. As expected, the below code is not working. Can anyone please help me with this logic or correct my code if it's a minor logical mistake.
var cfk = from p in db.Questions
where p.ItemId == Convert.ToInt32(c)
select p;
GridView4.DataSource = cfk;
GridView4.DataBind();
Something like:
var cfk = from p in db.Questions
where c.Contains(p.ItemId)
select p;
You can perform an inner join using LINQ.
http://msdn.microsoft.com/en-us/library/bb397941.aspx
I would probably do the join on the Db side during your Get() if possible, though.
Based on your choice of 'cfk' as the second variable name I'm guessing you have setup your database such that Questions.ItemId is a foreign key into Testings, where Testings.ItemId is the primary key of Testings and Testings.id is some other non-key column.
If that is the case you can say:
var cfk = db.Testings
.Where(t => t.id == k)
.SelectMany(t => t.Questions);
or
var cfk = db.Questions
.Where(t => t.Testing.id == k);
If there is no foreign key relationship you would need to do a Join as others suggest e.g.
var cfk = db.Testings
.Where(t => t.id == k)
.Join(db.Questions, t => t.ItemId, q => q.ItemId, (t, q) => q);