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();
Related
I have a two tables Customers, and ConnectedCustomers. That means customers can connect with each other.
My question is how can I get all Customers which are related to Chris (id = 3).
I should as a results get Bob and John..
I've tried something like this:
query = _context.Customers.Where(c =>_context.ConnectedCustomers.Any(cc => cc.Connected_Customer1.Equals(3) || cc.Connected_Customer2.Equals(3)));
But this is not working it returns too many rows..
Expected result for id 3 is BOB AND JOHN because they are connected
with id 3.
Thanks guys
Cheers
var answer = (from cc in _context.ConnectedCustomers
join c1 in _context.Customers on cc.Connected_Customer1 equals c1.id
join c2 in _context.Customers on cc.Connected_Customer2 equals c2.id
where c1.id == 3 || c2.id == 3
select c1.id == 3 ? c2 : c1
).ToList();
The problem in your query is you are querying from Customer table. When you are querying through Customer, what it's doing is getting all the possible combinations of Fk with Connected_Customer1 and Connected_Customer2 which satisfies the condition.
What you should be doing is query from ConnectedCustomers.
Try this:
var result = _context.ConnectedCustomers
.Where(x => x.Connected_Customer1.Equals(3) || x.Connected_Customer2.Equals(3))
.Select(x=>x.Customers)
.ToList();
You never use the id of the user to check (c), so you have to add a condition like this :
var query = _context.Customers.Where(customer => _context.ConnectedCustomers.Any(cc =>
cc.Connected_Customer1.Equals(customer.Id) && cc.Connected_Customer2.Equals(3) ||
cc.Connected_Customer1.Equals(3) && cc.Connected_Customer2.Equals(customer.Id))).ToList();
_context.Customers.Where(c => c.Id == _context.ConnectedCustomers.Where(cc => cc.Connected_Customer1 == 3).Select(cc => cc.Connected_Customer2))
Try that.
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 need to get NewsImage field and list of categories Ids that associated with the news in Many to Many relationship ... but it gives me error:
The type of one of the expressions in the join clause is incorrect.Type inference failed in the call to 'Join'.
My code looks like this
var Result1 = (from c in db.News
join d in db.Categories
on c.NewsId equals d.News.Select(l => l.NewsId)
where c.NewsId == 1
select new { c.NewsImagePath, d.CategoryId }).ToList();
Assuming you have a navigation property defining the n-n relation I would write:
var result = db.News
.Where(x => x.NewsId == 1)
.SelectMany(x => x.Categories,
(news, category) => new { news.NewsImagePath, category.CategoryId })
.ToList();
The problem is inside the on statement.
on c.NewsId equals d.News.Select( l => l.NewsId )
The Select on the right-hand side will return a IEnumerable of news, which is not what you want.
Something like this would technically work:
on c.NewsId equals d.News.Select( l => l.NewsId ).FirstOrDefault()
But it does not make sense logically.
I suspect the whole query should be built differently. I think you want to join when the category list of news contains the news item. In that case, you can't use the join statement, it would look somewhat like this:
from n in db.News
from c in db.Categories
where c.News.Select( ne => ne.NewsId ).Contains( n.NewsId )
select new { n.NewsImagePath, c.CategoryId }
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));
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);