EF6 Linq to Sql column alias exceeds 30 characters - c#
I am converting our Data Access Layer from Telerik ORM (deprecated) to EF 6. It connects to an Oracle 12c datasource with a 30 character limit. Some table names and column names are exactly 30 characters (as in this example below), some are shorter.
The Linq to Sql queries already exist and worked find with Telerik because it used alias for column names as t1, t2, etc.. whereas EF apparently copies the original column name as the alias. In most cases this works except for code table joins where both the PK of the code table and the FK of the parent table are exactly the same, then it appends a 1 to the end of the column alais thus making it 31 characters. As you can guess Oracle complains.
I need to find a way to force EF to use a shorter alias, any way to do this?
Here is the Linq query:
var dbElevationsHistory = (from elevationHist in dbContext.ElevationDataReadingJournals
join it in dbContext.MeasurementIssueTypes on elevationHist.MeasurementIssueTypeId equals it.MeasurementIssueTypeId into iType
from issueType in iType.DefaultIfEmpty()
join mt in dbContext.ElevationMeasureMethodTypes on elevationHist.ElevationMeasureMethodTypeId equals mt.ElevationMeasureMethodTypeId into mType
from methodType in mType.DefaultIfEmpty()
join at in dbContext.ElevationAccuracyTypes on elevationHist.ElevationAccuracyTypeId equals at.ElevationAccuracyTypeId into aType
from accuracyType in aType.DefaultIfEmpty()
join cAgency in dbContext.Organizations on elevationHist.CoopAgencyOrganizationId equals cAgency.OrganizationId into foundAgencies
from coopAgency in foundAgencies.DefaultIfEmpty()
where elevationHist.StationId == wellKey
select new { elevationHist, issueType, accuracyType, methodType, coopAgency })
.OrderByDescending(eh => eh.elevationHist.ModifiedDate)
.OrderByDescending(eh => eh.elevationHist.ElevationDataReadingJournalId);
And the sql query it produces:
SELECT
"Project1"."C1" AS "C1",
"Project1"."EWM_ELEVATION_DATA_READ_JRL_ID" AS "EWM_ELEVATION_DATA_READ_JRL_ID",
"Project1"."EWM_ELEVATION_DATA_READING_ID" AS "EWM_ELEVATION_DATA_READING_ID",
"Project1"."CRUD_TYPE" AS "CRUD_TYPE",
"Project1"."CRUD_DT" AS "CRUD_DT",
"Project1"."MEASUREMENT_DT" AS "MEASUREMENT_DT",
"Project1"."ORG_ID" AS "ORG_ID",
"Project1"."EWM_MEASUREMENT_ISSUE_TYPE_ID" AS "EWM_MEASUREMENT_ISSUE_TYPE_ID",
"Project1"."EWM_STATION_ID" AS "EWM_STATION_ID",
"Project1"."EWM_ELEV_MEASURE_METHOD_TYP_ID" AS "EWM_ELEV_MEASURE_METHOD_TYP_ID",
"Project1"."EWM_ELEVATION_ACCURACY_TYPE_ID" AS "EWM_ELEVATION_ACCURACY_TYPE_ID",
"Project1"."REFERENCE_POINT_ELEVATION" AS "REFERENCE_POINT_ELEVATION",
"Project1"."GROUND_SURFACE_ELEVATION" AS "GROUND_SURFACE_ELEVATION",
"Project1"."WATER_SURFACE_READING" AS "WATER_SURFACE_READING",
"Project1"."REFERENCE_POINT_READING" AS "REFERENCE_POINT_READING",
"Project1"."MANDATORY_READING" AS "MANDATORY_READING",
"Project1"."COMMENTS" AS "COMMENTS",
"Project1"."MODIFIED_DATE" AS "MODIFIED_DATE",
"Project1"."MODIFIED_USER" AS "MODIFIED_USER",
"Project1"."MODIFIED_PROC" AS "MODIFIED_PROC",
"Project1"."COOPERATING_AGENCY_ORG_ID" AS "COOPERATING_AGENCY_ORG_ID",
"Project1"."APPL_ID" AS "APPL_ID",
"Project1"."SUBMISSION_DATE" AS "SUBMISSION_DATE",
"Project1"."EWM_MEASUREMENT_ISSUE_TYPE_ID1" AS "EWM_MEASUREMENT_ISSUE_TYPE_ID1",
"Project1"."EWM_MEASURE_ISSUE_TYPE_CODE" AS "EWM_MEASURE_ISSUE_TYPE_CODE",
"Project1"."EWM_MEASURE_ISSUE_TYPE_DESC" AS "EWM_MEASURE_ISSUE_TYPE_DESC",
"Project1"."EWM_MEASURE_ISSUE_TYPE_ACTV" AS "EWM_MEASURE_ISSUE_TYPE_ACTV",
"Project1"."EWM_MEASURE_ISSUE_TYPE_ORDER" AS "EWM_MEASURE_ISSUE_TYPE_ORDER",
"Project1"."EWM_MEASURE_ISSUE_TYPE_CLASS" AS "EWM_MEASURE_ISSUE_TYPE_CLASS",
"Project1"."MODIFIED_DATE1" AS "MODIFIED_DATE1",
"Project1"."MODIFIED_USER1" AS "MODIFIED_USER1",
"Project1"."MODIFIED_PROC1" AS "MODIFIED_PROC1",
"Project1"."APPL_ID1" AS "APPL_ID1",
"Project1"."EWM_ELEVATION_ACCURACY_TYPE_ID1" AS "EWM_ELEVATION_ACCURACY_TYPE_ID1",
"Project1"."EWM_ELEVATION_ACCURACY_DESC" AS "EWM_ELEVATION_ACCURACY_DESC",
"Project1"."EWM_ELEVATION_ACCURACY_ACTV" AS "EWM_ELEVATION_ACCURACY_ACTV",
"Project1"."EWM_ELEVATION_ACCURACY_ORDER" AS "EWM_ELEVATION_ACCURACY_ORDER",
"Project1"."MODIFIED_DATE3" AS "MODIFIED_DATE2",
"Project1"."MODIFIED_USER3" AS "MODIFIED_USER2",
"Project1"."MODIFIED_PROC3" AS "MODIFIED_PROC2",
"Project1"."EWM_ELEVATION_ACCURACY_CD" AS "EWM_ELEVATION_ACCURACY_CD",
"Project1"."APPL_ID3" AS "APPL_ID2",
"Project1"."EWM_ELEV_MEASURE_METHOD_TYP_ID1" AS "EWM_ELEV_MEASURE_METHOD_TYP_ID1",
"Project1"."EWM_ELEV_MEASURE_METHOD_DESC" AS "EWM_ELEV_MEASURE_METHOD_DESC",
"Project1"."EWM_ELEV_MEASURE_METHOD_ACTV" AS "EWM_ELEV_MEASURE_METHOD_ACTV",
"Project1"."EWM_ELEV_MEASURE_METHOD_ORDER" AS "EWM_ELEV_MEASURE_METHOD_ORDER",
"Project1"."MODIFIED_DATE2" AS "MODIFIED_DATE3",
"Project1"."MODIFIED_USER2" AS "MODIFIED_USER3",
"Project1"."MODIFIED_PROC2" AS "MODIFIED_PROC3",
"Project1"."EWM_ELEV_MEASURE_METHOD_CD" AS "EWM_ELEV_MEASURE_METHOD_CD",
"Project1"."APPL_ID2" AS "APPL_ID3",
"Project1"."ORG_ID1" AS "ORG_ID1",
"Project1"."ORG_NAME" AS "ORG_NAME",
"Project1"."ORG_ABBR" AS "ORG_ABBR",
"Project1"."ORG_TYPE_ID" AS "ORG_TYPE_ID",
"Project1"."MODIFIED_DATE4" AS "MODIFIED_DATE4",
"Project1"."MODIFIED_USER4" AS "MODIFIED_USER4",
"Project1"."MODIFIED_PROC4" AS "MODIFIED_PROC4",
"Project1"."ORG_TIN" AS "ORG_TIN"
FROM ( SELECT
"Extent1"."EWM_ELEVATION_DATA_READ_JRL_ID" AS "EWM_ELEVATION_DATA_READ_JRL_ID",
"Extent1"."EWM_ELEVATION_DATA_READING_ID" AS "EWM_ELEVATION_DATA_READING_ID",
"Extent1"."CRUD_TYPE" AS "CRUD_TYPE",
"Extent1"."CRUD_DT" AS "CRUD_DT",
"Extent1"."MEASUREMENT_DT" AS "MEASUREMENT_DT",
"Extent1"."ORG_ID" AS "ORG_ID",
"Extent1"."EWM_MEASUREMENT_ISSUE_TYPE_ID" AS "EWM_MEASUREMENT_ISSUE_TYPE_ID",
"Extent1"."EWM_STATION_ID" AS "EWM_STATION_ID",
"Extent1"."EWM_ELEV_MEASURE_METHOD_TYP_ID" AS "EWM_ELEV_MEASURE_METHOD_TYP_ID",
"Extent1"."EWM_ELEVATION_ACCURACY_TYPE_ID" AS "EWM_ELEVATION_ACCURACY_TYPE_ID",
"Extent1"."REFERENCE_POINT_ELEVATION" AS "REFERENCE_POINT_ELEVATION",
"Extent1"."GROUND_SURFACE_ELEVATION" AS "GROUND_SURFACE_ELEVATION",
"Extent1"."WATER_SURFACE_READING" AS "WATER_SURFACE_READING",
"Extent1"."REFERENCE_POINT_READING" AS "REFERENCE_POINT_READING",
"Extent1"."MANDATORY_READING" AS "MANDATORY_READING",
"Extent1"."COMMENTS" AS "COMMENTS",
"Extent1"."MODIFIED_DATE" AS "MODIFIED_DATE",
"Extent1"."MODIFIED_USER" AS "MODIFIED_USER",
"Extent1"."MODIFIED_PROC" AS "MODIFIED_PROC",
"Extent1"."COOPERATING_AGENCY_ORG_ID" AS "COOPERATING_AGENCY_ORG_ID",
"Extent1"."APPL_ID" AS "APPL_ID",
"Extent1"."SUBMISSION_DATE" AS "SUBMISSION_DATE",
1 AS "C1",
"Extent2"."EWM_MEASUREMENT_ISSUE_TYPE_ID" AS "EWM_MEASUREMENT_ISSUE_TYPE_ID1",
"Extent2"."EWM_MEASURE_ISSUE_TYPE_CODE" AS "EWM_MEASURE_ISSUE_TYPE_CODE",
"Extent2"."EWM_MEASURE_ISSUE_TYPE_DESC" AS "EWM_MEASURE_ISSUE_TYPE_DESC",
"Extent2"."EWM_MEASURE_ISSUE_TYPE_ACTV" AS "EWM_MEASURE_ISSUE_TYPE_ACTV",
"Extent2"."EWM_MEASURE_ISSUE_TYPE_ORDER" AS "EWM_MEASURE_ISSUE_TYPE_ORDER",
"Extent2"."EWM_MEASURE_ISSUE_TYPE_CLASS" AS "EWM_MEASURE_ISSUE_TYPE_CLASS",
"Extent2"."MODIFIED_DATE" AS "MODIFIED_DATE1",
"Extent2"."MODIFIED_USER" AS "MODIFIED_USER1",
"Extent2"."MODIFIED_PROC" AS "MODIFIED_PROC1",
"Extent2"."APPL_ID" AS "APPL_ID1",
"Extent3"."EWM_ELEV_MEASURE_METHOD_TYP_ID" AS "EWM_ELEV_MEASURE_METHOD_TYP_ID1",
"Extent3"."EWM_ELEV_MEASURE_METHOD_DESC" AS "EWM_ELEV_MEASURE_METHOD_DESC",
"Extent3"."EWM_ELEV_MEASURE_METHOD_ACTV" AS "EWM_ELEV_MEASURE_METHOD_ACTV",
"Extent3"."EWM_ELEV_MEASURE_METHOD_ORDER" AS "EWM_ELEV_MEASURE_METHOD_ORDER",
"Extent3"."MODIFIED_DATE" AS "MODIFIED_DATE2",
"Extent3"."MODIFIED_USER" AS "MODIFIED_USER2",
"Extent3"."MODIFIED_PROC" AS "MODIFIED_PROC2",
"Extent3"."EWM_ELEV_MEASURE_METHOD_CD" AS "EWM_ELEV_MEASURE_METHOD_CD",
"Extent3"."APPL_ID" AS "APPL_ID2",
**"Extent4"."EWM_ELEVATION_ACCURACY_TYPE_ID" AS "EWM_ELEVATION_ACCURACY_TYPE_ID1"**,
"Extent4"."EWM_ELEVATION_ACCURACY_DESC" AS "EWM_ELEVATION_ACCURACY_DESC",
"Extent4"."EWM_ELEVATION_ACCURACY_ACTV" AS "EWM_ELEVATION_ACCURACY_ACTV",
"Extent4"."EWM_ELEVATION_ACCURACY_ORDER" AS "EWM_ELEVATION_ACCURACY_ORDER",
"Extent4"."MODIFIED_DATE" AS "MODIFIED_DATE3",
"Extent4"."MODIFIED_USER" AS "MODIFIED_USER3",
"Extent4"."MODIFIED_PROC" AS "MODIFIED_PROC3",
"Extent4"."EWM_ELEVATION_ACCURACY_CD" AS "EWM_ELEVATION_ACCURACY_CD",
"Extent4"."APPL_ID" AS "APPL_ID3",
"Extent5"."ORG_ID" AS "ORG_ID1",
"Extent5"."ORG_NAME" AS "ORG_NAME",
"Extent5"."ORG_ABBR" AS "ORG_ABBR",
"Extent5"."ORG_TYPE_ID" AS "ORG_TYPE_ID",
"Extent5"."MODIFIED_DATE" AS "MODIFIED_DATE4",
"Extent5"."MODIFIED_USER" AS "MODIFIED_USER4",
"Extent5"."MODIFIED_PROC" AS "MODIFIED_PROC4",
"Extent5"."ORG_TIN" AS "ORG_TIN"
FROM "EWM_ADM"."EWM_ELEVATION_DATA_READING_JRL" "Extent1"
LEFT OUTER JOIN "EWM_ADM"."EWM_MEASUREMENT_ISSUE_TYPE" "Extent2" ON "Extent1"."EWM_MEASUREMENT_ISSUE_TYPE_ID" = "Extent2"."EWM_MEASUREMENT_ISSUE_TYPE_ID"
LEFT OUTER JOIN "EWM_ADM"."EWM_ELEV_MEASURE_METHOD_TYP" "Extent3" ON "Extent1"."EWM_ELEV_MEASURE_METHOD_TYP_ID" = "Extent3"."EWM_ELEV_MEASURE_METHOD_TYP_ID"
LEFT OUTER JOIN "EWM_ADM"."EWM_ELEVATION_ACCURACY_TYPE" "Extent4" ON "Extent1"."EWM_ELEVATION_ACCURACY_TYPE_ID" = "Extent4"."EWM_ELEVATION_ACCURACY_TYPE_ID"
LEFT OUTER JOIN "BUS_ADM"."ORGANIZATION" "Extent5" ON "Extent1"."COOPERATING_AGENCY_ORG_ID" = "Extent5"."ORG_ID"
WHERE (("Extent1"."EWM_STATION_ID" = 52370) OR (("Extent1"."EWM_STATION_ID" IS NULL) AND (52370 IS NULL)))
) "Project1"
ORDER BY "Project1"."EWM_ELEVATION_DATA_READ_JRL_ID" DESC
The line in question is this one (marked with asterisks in the query since I cannot bold it).
"Extent4"."EWM_ELEVATION_ACCURACY_TYPE_ID" AS "EWM_ELEVATION_ACCURACY_TYPE_ID1"
As you can see it appended a 1 to the alias. I need to prevent that or force a custom alias name.
Related
LINQ Null Join with Pivot Table
I'm trying to get a list of servers thay may or may not belong to 1 or more groups to display in a grid. Example ServerID IP GroupID 1 192.168.1.44 1 1 192.168.1.44 10 2 192.168.1.45 1 3 192.168.1.46 2 4 192.168.1.47 null 5 192.168.1.48 null If I have no records In the GroupServer Table. (Since there is no groups or groups exist but they are not assigned) I expect to get something like this: ServerID IP GroupID 1 192.168.1.44 null 2 192.168.1.45 null 3 192.168.1.46 null 4 192.168.1.47 null 5 192.168.1.48 null Since is a Many-to-Many relationship. I have Group Table Server Table GroupServer Table I could not find a LINQ Pivot Table example. So I tried to buid my own. var query = (from sg in context.ServerGroups join servers in context.Servers on sg.ServerID equals servers.ID join groups in context.Groups on sg.GroupID equals groups.ID into serverxgroup from gAddrBilling in serverxgroup.DefaultIfEmpty() select new { ServerID = sg.ServerID, ServerIP = server.IP, GroupID = sg.GroupID }); The Query above does not retrieve anything And I quiet dont understand what the "from gAddrBilling" is for. Since I modify a snippet I was trying to make work. So I wonder if someone has already faced a problem like this and give me some hint, snippet or advice about what is what I'm missing. Thank you.
First, this is not a pivot query, but a regular query on many-to-may relationship via explicit junction table. Second, looks like you are using Entity Framework, in which case you'd better define and use navigation properties rather than manual joins. Third, and the most important, the structure of the query is wrong. If you want to get a list of servers that may or may not belong to 1 or more groups, then you should start your query from Servers (the table which records you want to be always included, not from link table where some ServerID are missing) and then use left outer joins to the other tables like this: var query = from s in servers in context.Servers join sg in context.ServerGroups on s.ID equals sg.ServerID into s_sg from sg in s_sg.DefaultIfEmpty() // make the above LEFT OUTER JOIN // You can remove the next two lines if all you need is the GroupId // and keep them if you need some other Group field in the select join g in context.Groups on sg.GroupID equals g.ID into sg_g from g in sg_g.DefaultIfEmpty() // make the above LEFT OUTER JOIN select new { ServerID = s.ID, ServerIP = s.IP, // or sg.IP? GroupID = (int?)sg.GroupID };
How do I use multiple IDs from a table with an INNER JOIN using SQL?
I have a list of SiteUsers in one table and another table has columns with different types of owners (ID) for the record. For example, the SiteUserID in the SiteUsers table will be used for the SalesRepID, the StaffingManagerID, and RecruiterID in the Fill table. Of course, the SiteUserID is different for each of the values in the Fill table. I'd like to return the name of the SiteUser for each ID column in the Fill Table. How do I properly construct a JOIN statement to do this? I'm guessing this is done through INNER JOIN, but I'm not sure. My current select statement already has an INNER JOIN as I'm pulling the name of the FillType from another table. I'm using this in an asp.net application. I'm not sure if this is even possible. Any help is appreciated.
Since each of the IDs in the Fills table allows null, you probably want to LEFT JOIN to the SiteUsers table like so: SELECT f.FillID, s1.SiteUserLastName 'SalesRep', s2.SiteUserLastName 'StaffingManager', s3.SiteUserLastName 'Recruiter' FROM Fills f LEFT JOIN SiteUsers s1 on f.SalesRepID = s1.SiteUserID LEFT JOIN SiteUsers s2 on f.StaffingManagerID = s2.SiteUserID LEFT JOIN SiteUsers s3 on f.RecruiterID = s3.SiteUserID
You can always UNPIVOT the results like so: SELECT DISTINCT unpvt.FillID ,unpvt.RepID ,unpvt.RepType ,s.SiteUserFirstName ,s.SiteUserLastName FROM (SELECT FillID ,SalesRepID ,StaffingManagerID ,RecruiterID FROM Fills ) f UNPIVOT (RepID FOR RepType IN (SalesRepID, StaffingManagerID,RecruiterID) ) AS unpvt JOIN SiteUsers AS s on unpvt.RepID = s.SiteUserID` Obviously you can play with exact output (such as substituting the RepType for a different value with a CASE statement or whatnot. My question is: why the piss-poor design? Instead of having three IDs in the Fills table, you should have a junction table between SiteUsers and Fills to allow many-to-many relationships. IF it were designed with a junction table, you'd never have had to ask this question.
You will have to join the Fill table with the SiteUsers table multiple times, one for each xxxID column in the Fills for which you want the SiteUser name and combine the results using an union as below: select a.SiteUserId, a.SiteUserFirstName, a.SiteUserLastName from dbo.SiteUsers a inner join dbo.Fills b on b.SalesRepId = a.SiteUserId UNION select a.SiteUserId, a.SiteUserFirstName, a.SiteUserLastName from dbo.SiteUsers a inner join dbo.Fills b on b.StaffingManagerId = a.SiteUserId UNION select a.SiteUserId, a.SiteUserFirstName, a.SiteUserLastName from dbo.SiteUsers a inner join dbo.Fills b on b.RecruiterId = a.SiteUserId
Is this LINQ Query "correct"?
I have the following LINQ query, that is returning the results that I expect, but it does not "feel" right. Basically it is a left join. I need ALL records from the UserProfile table. Then the LastWinnerDate is a single record from the winner table (possible multiple records) indicating the DateTime the last record was entered in that table for the user. WinnerCount is the number of records for the user in the winner table (possible multiple records). Video1 is basically a bool indicating there is, or is not a record for the user in the winner table matching on a third table Objective (should be 1 or 0 rows). Quiz1 is same as Video 1 matching another record from Objective Table (should be 1 or 0 rows). Video and Quiz is repeated 12 times because it is for a report to be displayed to a user listing all user records and indicate if they have met the objectives. var objectiveIds = new List<int>(); objectiveIds.AddRange(GetObjectiveIds(objectiveName, false)); var q = from up in MetaData.UserProfile select new RankingDTO { UserId = up.UserID, FirstName = up.FirstName, LastName = up.LastName, LastWinnerDate = ( from winner in MetaData.Winner where objectiveIds.Contains(winner.ObjectiveID) where winner.Active where winner.UserID == up.UserID orderby winner.CreatedOn descending select winner.CreatedOn).First(), WinnerCount = ( from winner in MetaData.Winner where objectiveIds.Contains(winner.ObjectiveID) where winner.Active where winner.UserID == up.UserID orderby winner.CreatedOn descending select winner).Count(), Video1 = ( from winner in MetaData.Winner join o in MetaData.Objective on winner.ObjectiveID equals o.ObjectiveID where o.ObjectiveNm == Constants.Promotions.SecVideo1 where winner.Active where winner.UserID == up.UserID select winner).Count(), Quiz1 = ( from winner2 in MetaData.Winner join o2 in MetaData.Objective on winner2.ObjectiveID equals o2.ObjectiveID where o2.ObjectiveNm == Constants.Promotions.SecQuiz1 where winner2.Active where winner2.UserID == up.UserID select winner2).Count(), };
You're repeating join winners table part several times. In order to avoid it you can break it into several consequent Selects. So instead of having one huge select, you can make two selects with lesser code. In your example I would first of all select winner2 variable before selecting other result properties: var q1 = from up in MetaData.UserProfile select new {up, winners = from winner in MetaData.Winner where winner.Active where winner.UserID == up.UserID select winner}; var q = from upWinnerPair in q1 select new RankingDTO { UserId = upWinnerPair.up.UserID, FirstName = upWinnerPair.up.FirstName, LastName = upWinnerPair.up.LastName, LastWinnerDate = /* Here you will have more simple and less repeatable code using winners collection from "upWinnerPair.winners"*/
The query itself is pretty simple: just a main outer query and a series of subselects to retrieve actual column data. While it's not the most efficient means of querying the data you're after (joins and using windowing functions will likely get you better performance), it's the only real way to represent that query using either the query or expression syntax (windowing functions in SQL have no mapping in LINQ or the LINQ-supporting extension methods). Note that you aren't doing any actual outer joins (left or right) in your code; you're creating subqueries to retrieve the column data. It might be worth looking at the actual SQL being generated by your query. You don't specify which ORM you're using (which would determine how to examine it client-side) or which database you're using (which would determine how to examine it server-side). If you're using the ADO.NET Entity Framework, you can cast your query to an ObjectQuery and call ToTraceString(). If you're using SQL Server, you can use SQL Server Profiler (assuming you have access to it) to view the SQL being executed, or you can run a trace manually to do the same thing. To perform an outer join in LINQ query syntax, do this: Assuming we have two sources alpha and beta, each having a common Id property, you can select from alpha and perform a left join on beta in this way: from a in alpha join btemp in beta on a.Id equals btemp.Id into bleft from b in bleft.DefaultIfEmpty() select new { IdA = a.Id, IdB = b.Id } Admittedly, the syntax is a little oblique. Nonetheless, it works and will be translated into something like this in SQL: select a.Id as IdA, b.Id as Idb from alpha a left join beta b on a.Id = b.Id
It looks fine to me, though I could see why the multiple sub-queries could trigger inefficiency worries in the eyes of a coder. Take a look at what SQL is produced though (I'm guessing you're running this against a database source from your saying "table" above), before you start worrying about that. The query providers can be pretty good at producing nice efficient SQL that in turn produces a good underlying database query, and if that's happening, then happy days (it will also give you another view on being sure of the correctness).
How do I join tables with a condition using LLBLGen?
I have the following Sql Query that returns the type of results that I want: SELECT b.ID, a.Name, b.Col2, b.COl3 FROM Table1 a LEFT OUTER JOIN Table2 b on b.Col4 = a.ID AND b.Col5 = 'test' In essence, I want a number of rows equal to Table1 (a) while having the data from Table2 (b) listed or NULL if the condition, 'test', doesn't exist in Table2. I'm rather new to LLBLGen and have tried a few things and it isn't working. I can get it to work if the condition exists; however, when a requirements change came in and caused me to rewrite the query to that above, I'm at a loss. Below is the old LLBLGen C# code that worked for existing products but not for the above query: LookupTable2Collection table2col = new LookupTable2Collection(); RelationCollection relationships = new RelationCollection(); relationships.Add(LookupTable2Entity.Relations.LookupTable1EntityUsingTable1ID, JoinHint.Left); IPredicateExpression filter = new PredicateExpression(); filter.Add(new FieldCompareValuePredicate(LookupTable2Fields.Col5, ComparisonOperator.Equal, "test")); table2col.GetMulti(filter, relationships); Table 1 has 3 records in it. I need the 3 records back even if all items from Table 2 are NULL because the condition doesn't exist. Any ideas?
You've to add your filter to the relation join like this: relationships.Add(LookupTable2Entity.Relations.LookupTable1EntityUsingTable1ID, JoinHint.Left).CustomFilter = new FieldCompareValuePredicate(LookupTable2Fields.Col5, ComparisonOperator.Equal, "test");
Advice on removing multiple sub-queries (which contains a join) by optimizing Linq To SQL query
I'm working on adding globalization to my product cataloge and I have made it work. However, I feel that the underlaying SQL query isn't performing as well as it could and I could need some advice on how to change my Linq To SQL query to make it more efficient. The tables that are used Product contains a unique id for each product. This column is called EntityID TextTranslation contains the globalized text. The columns in this table are CultureID (a string), TextID (a reference to the text), Value (the actuall globalized text). Text contains the mapping between a globalized text and a product. There is also a column which indicates which type of text it is (like name, description and so on) TextType contains the definition (id, name and description) for a text type. var culturedTexts = from translation in ctx.TextTranslations join text in ctx.Texts on translation.TextId equals text.TextId where translation.CultureId == "en-EN" select new { text.EntityId, text.TextTypeId, translation.Value, }; var products = from p in ctx.Products let texts = culturedTexts.Where(i => i.EntityId == p.EntityId) select new Model.Product { Description = texts.Where(c => c.TextTypeId == (int)TextType.Description).SingleOrDefault().Value, Name = texts.Where(c => c.TextTypeId == (int)TextType.Name).SingleOrDefault().Value }; When this is executed I get a query which looks like SELECT ( SELECT [t1].[Value] FROM [Common].[TextTranslation] AS [t1] INNER JOIN [Common].[Text] AS [t2] ON [t1].[TextId] = [t2].[TextId] WHERE ([t2].[TextTypeId] = 2) AND ([t2].[EntityId] = [t0].[EntityId]) AND ([t1].[CultureId] = 'sv-SE') ) AS [Description], ( SELECT [t3].[Value] FROM [Common].[TextTranslation] AS [t3] INNER JOIN [Common].[Text] AS [t4] ON [t3].[TextId] = [t4].[TextId] WHERE ([t4].[TextTypeId] = 1) AND ([t4].[EntityId] = [t0].[EntityId]) AND ([t3].[CultureId] = 'sv-SE') ) AS [Name] FROM [Catalog].[Product] AS [t0] So each globalized text (Name, Description) in the LINQ query gets its own sub query and associated join. Is it possible to streamline this a bit and remove each text type getting its own join and subquery?
Well, given that they are getting different TextTypeId values, how would you prefer the TSQL to look? If you do a single JOIN, you'll have to put in a messy SELECT CASE or similar to discriminate between type "1" and type "2". One option would be to to simply bring back all the suitable rows and do the final projection in-memory at the client, but to be honest I expect that the SQL optimizer will make light work of that TSQL anyway... especially if that query hits a good spanning index.