Correct Join statement in Linq - c#

I searched for the answer of my question, since am a beginner am not able to get those all, so asked my own,
I have two tables SUBMENU and AUTHORIZATION am tryin to put a join but not clear whether to put left or right or some other way, since am new to linq.
Here is what i have done so far,
var _lststage =
from sm in db.SUB_MENUs
join a in db.AUTHORISATIONs
on sm.SUB_MENU_ID equals a.SUB_MENU_ID into joined_autho
from jA in joined_autho.DefaultIfEmpty()
where sm.MENU_ID.Equals(ViewState["MenuId"]) &&
jA.Roleid Equals ddlroleid.Selectedvalue
select new
{
sm.SUB_MENU_ID,
sm.SUB_MENU_NAME,
jA.checkbox,
};
I want to get all the submenus from the submenu table based on the menuid in view state, and,
I need to get the value for check box in Authorization table based on the role id and submenuid, and if there is no value for that role id in authorization table default false value should return.
Hope i explained my scenario well,
Possibilities of duplicate question...
Sorry if.

Your query even will not compile. In your where condition second Equals should be method call:
// instead of: jA.Roleid Equals ddlroleid.Selectedvalue
jA.Roleid.Equals(ddlroleid.Selectedvalue)
Also you have unnecessary comma on last line of select statement:
// instead of: jA.checkbox,
jA.checkbox
Complete query should look like:
from sm in db.SUB_MENUs
join a in db.AUTHORISATIONs
on sm.SUB_MENU_ID equals a.SUB_MENU_ID into joined_autho
from jA in joined_autho.DefaultIfEmpty()
where sm.MENU_ID.Equals(ViewState["MenuId"]) &&
jA.Roleid.Equals(ddlroleid.Selectedvalue)
select new
{
sm.SUB_MENU_ID,
sm.SUB_MENU_NAME,
jA.checkbox
};
I believe you have tagged your question appropriately, and this is Linq to SQL query.

Related

LINQ Join Query Structure Resulting in CS0119 Error

I'm trying to join two different class models in an MVC project together so I can order them ascending/descending. I've tried several permutations but can't seem to get the LINQ query to play nice. Any suggestions on what I'm doing wrong?
var lateContact = from c in JPLatestContact
join s in JPStudent on c.ApplicationUserId equals
s.ApplicationUserId
orderby c.JPLatestContactDate ascending
select s;
I'm a beginner when it comes to this, but if I'm understanding this correctly, the "c" and "s" are variables I make up myself. "JPLatestContact" and "JPStudent" are the two models/classes/tables I want to join, and both have "ApplicationUserId" that I can join them on, and I want to order all the results by the value "JPLatestContactDate" found in the JPLatestContact model, in ascending order.
With the query I've written above, I'm getting a CS0119 error "'JPLatestContact' is a type, which is not valid in the given context."
I'm not sure where I'm going wrong with my structure, or have I misused the JOIN structure in some way?
You cannot run a LINQ select on a type, only on a collection of that type - i.e. anything that implements IEnumerable<JPLatestContact> or IQueryable<JPLatestContact>, such as List<JPLatestContact>, dbContext.JPLatestContact, etc. Same goes for JPStudent - you need a collection or IQueryable<JPStudent> for it.
Assuming that you are querying EF, the query should look like this:
var lateContact = from c in dbContext.JPLatestContact
join s in dbContext.JPStudent on c.ApplicationUserId equals
s.ApplicationUserId
orderby c.JPLatestContactDate ascending
select s;
Make sure that all entity names and property names match the actual names as defined in your EF model.

generic cross join on table based on user choice of column

I need to perform a cross join on a table columns in my database. I use linq and C# to do this. Here is the code i wrote:
var res = (from item_1 in set1
join item_2 in set_2 on new
{
item_1.columnA,
item_1.columnB,
item_1.columnC,
item_1.columnD,
item_1.columnE,
//etc...
}
equals new
{
item_2.columnA,
item_2.columnB,
item_2.columnC,
item_2.columnD,
item_2.columnE,
//etc...
}
select new { item_1,item_2};
I have an asp.net page where users can choose which columns they would like the cross joins to be performed on. And the query should reflect their choice. Some users would only want 2 of of the columns to be used while other will select 10.
I obviously do not want to repeat this query in some switch statement and include the selected columns. I'm wandering if there is a generic way of doing this. Passing a lambda expression ... I'm just not sure how this should be done.
Any help will highly be appreciated.
Take a look at this blogpost from Scott Gu about Dynamic LinQ.
It not only contains an explanation on the matter, links to downloads and examples are also provided. Hope this helps!

Exception in a CRM LINQ query with joins. Attribute in second table doesn't exist

First of all I'm sorry because this is the second time that I write this question but before was bad explained and now is close.
I'm doing a linq query for a search page for a CRM data base, and wrtiting a normal query like below is not working, I'm getting the exception:
[System.ServiceModel.FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>] = {"'Contact' entity doesn't contain attribute with Name = 'title'."}
For a join query, that in the clause Where was something like r.Name == "Me" && j.LastName == "He" I had to did the query with two Where clauses, because I was getting the same exception as above, saying that table 'r' doesn't have 'LastName' attributte.
var cms = from i in aux_pr
join cal in Contact on i.aux_CallerRequestorID.Id equals cal.ContactId.Value
join sub in Subject on i.aux_ClassificationID.Id equals sub.SubjectId
where cal.FullName.Contains(searchTerm) ||
sub.Title.Contains(searchTerm)
In this case, how can I do this query. Thanks in advance!
I want to comment what have I learned and the solution that I have found to my problem hoping could help some one. There are some limitations in CRM LINQ, as explained here
The first that I found, having an entity reference like this:
CrmEntityReference Caller
{
Guid ID;
string name;
}
I can select Caller.name but I CAN'T have Caller.name in the where clause. Solution for this -> Join the table
The second limitation, is when we have joins in the query, we can have different tables in the where if they are an AND predicate, we have to write two clauses where like this:
where cal.FullName.Contains(searchTerm)
where sub.Title.Contains(searchTerm)
But the problem comes when instead of an AND we need use an OR predicate, the only solution we have is do two queries and after do an Union of these queries.
I have four queries for a call that could be done just with one, now in developing stage performance is good due to the amount of records, but we'll see in testing stage how this work.
try to create two different filters..
var cms = from i in aux_pr
join cal in Contact on i.aux_CallerRequestorID.Id equals cal.ContactId.Value
join sub in Subject on i.aux_ClassificationID.Id equals sub.SubjectId
where cal.FullName.Contains(searchTerm) ||
where sub.Title.Contains(searchTerm)

DefaultIfEmpty() Causing "System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable'"

Scenario: I have a table of User Profiles and a table of Colleagues. The colleagues table has a record for ever other user that a User Profile is following. In this query, I am grabbing all of the people who are following the current logged in user (getting their Record IDs from the Colleagues table and joining the User Profile table to get their details). Then, I am joining the Colleagues table again to see if the logged in user is following that user back.
Issue: It is my understanding that the best way to do a LEFT JOIN (in looking for the colleague record where the user is following the colleague back) is to add "DefaultIfEmpty()" to that join. When I add .DefaultIFEmpty() to that join, I get the following error message:
System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable'
If I remove the ".DefaultIFEmpty()" from that join, it works. However, it runs it as a regular JOIN, leaving out records where the user is not following the colleague back.
Code: Here is the code I am using:
var results = (from a1 in db.Colleague
join b1 in db.UserProfile on new {ColleagueId = a1.ColleagueId} equals
new {ColleagueId = b1.RecordId}
join d1 in db.UserProfile on new {RecordId = a1.OwnerId} equals
new {RecordId = d1.RecordId}
join c1 in db.Colleague
on new {OwnerId = b1.RecordId, Ignored = false, ColleagueId = a1.OwnerId}
equals new {c1.OwnerId, c1.Ignored, c1.ColleagueId} into c1Join
from c1 in c1Join.DefaultIfEmpty() // This is the .DefaultIfEmpty() breaking the query
where
b1.AccountName == userName &&
a1.Ignored == false
orderby
b1.LastName
select new
{
RecordId = (System.Int64?) d1.RecordId,
d1.AccountName,
d1.PreferredName,
d1.FirstName,
d1.LastName,
d1.PictureUrl,
d1.PublicUrl,
IsFollowing = c1.OwnerId < 1 ? 0 : 1
});
foreach (var result in results) // This is what throws the error
{
// Do stuff
}
Any ideas?
The SQL Provider for Entity Framework in version 3.5 of the .NET framework does not support DefaultIfEmpty(). Sorry, but could not find a better reference than this article: http://smehrozalam.wordpress.com/2009/06/10/c-left-outer-joins-with-linq/
You might want to try straight LINQ-to-SQL rather than ADO.NET Entity Framework. I believe that it works in LINQ-to-SQL. I've verified in the past that left joins work in 3.5 via LinqPad.
DefaultIfEmpty is supported only in EFv4+. First version of EF doesn't support DefaultInEmpty.
It looks like you need to create a default value to pass into DefaultIfEmpty(), since DefaultIsEmpty() takes a parameter.
DefaultIfEmpty() on MSDN

LINQ join behaving oddly

I am attempting to perform a join between two tables and limit results by 3 conditions. 2 of the conditions belong to the primary table, the third condition belongs to the secondary table. Here is the query I'm attempting:
var articles = (from article in this.Context.contents
join meta in this.Context.content_meta on article.ID equals meta.contentID
where meta.metaID == 1 && article.content_statusID == 1 && article.date_created > created
orderby article.date_created ascending
select article.content_text_key);
It is meant to join the two tables by the contentID, then filter based on the metaID (type of article), statusID, and then get all articles that are greater than the datetime created. The problem is that it returns 2 records (out of 4 currently). One has a date_created less than created and the other is the record that produced created in the first place (thus equal).
By removing the join and the where clause for the meta, the result produces no records (expected). What I can't understand is that when I translate this join into regular SQL it works just fine. Obviously I'm misunderstanding what the functionality of join is in this context. What would cause this behavior?
Edit:
Having tried this in LinqPad, I've noticed that LinqPad provides the expected results. I have tried these queries separately in code and it isn't until the join is added that odd results begin populating it appears to be happening on any date comparison where the record occurs on the same day as the limiter.
I can't seem to be able to add a comment but in debug mode you should be able to put a break point on this line of code. When you do you should be able to hover over it and have it tell you the sql that LINQ generates. Please post that sql.
At your suggestion, I'm posting my comment as the answer:
"It might also help to see your schema. The data types for metaID,
content_statusID, and date_created might come into play as well -- and
it's easy for me (somebody who's unfamiliar with your code) to make
assumptions about those data types."

Categories

Resources