LINQ Design time compile error - c#

Can someone please inform me what the correct syntax is for the below query?
I get a design time compile error beginning at the "equals" keyword at the following spot:
&& a.applicationid equals ga.applicationid
with the following error:
"A query body must end with a select clause or group clause"
I understand what the error means, but I can't see what the syntax error is....
public static List<ApplicationConfigurations> GetAppConfigs()
{
try
{
using (wmswebEntities DbContext = new wmswebEntities())
{
IEnumerable<ApplicationConfigurations> myAppConfigs = new IEnumerable<ApplicationConfigurations>();
myAppConfigs = (from a in DbContext.ApplicationConfigurations
join ga in DbContext.groupapplicationconfigurationslk on a.configurationid equals ga.configurationid
&& a.applicationid equals ga.applicationid
join g in DbContext.Groups on g.groupnumber equals ga.groupnumber
where a.ActiveFlag == true
&& ga.ActiveFlag == true
&& g.ActiveFlag == true
select
a.applicationconfigurations,
g.groupnumber).ToList();
return myAppConfigs;
}
}
catch (Exception ex)
{
throw ex;
}
}

The answer to this question has a very good explanation of why you cannot join on two fields in LINQ. It also suggests that you can either use an anonymous type to do the join, or you can simply move one of the conditions into the where clause. He's a quick example I put together in LINQPad to illustrate using a join for one of the conditions and a where for the other, and using join with an anonymous type.
var applicationConfigs = new[] {
new { ApplicationID = 1, ConfigurationID = 1, Name = "Application #1" },
new { ApplicationID = 2, ConfigurationID = 1, Name = "Application #2" },
new { ApplicationID = 3, ConfigurationID = 2, Name = "Application #3" },
new { ApplicationID = 4, ConfigurationID = 2, Name = "Application #4" }
};
var groupApplicationConfigs = new[] {
new { ApplicationID = 1, ConfigurationID = 1, Name = "Group App Config #1" },
new { ApplicationID = 1, ConfigurationID = 1, Name = "Group App Config #2" },
new { ApplicationID = 2, ConfigurationID = 1, Name = "Group App Config #3" },
new { ApplicationID = 3, ConfigurationID = 1, Name = "Group App Config #4" }
};
//JOIN + WHERE
var q = from a in applicationConfigs
join ga in groupApplicationConfigs
on a.ApplicationID equals ga.ApplicationID
where a.ConfigurationID == ga.ConfigurationID
select a;
Console.WriteLine(q);
//ANONYMOUS TYPE
var r = from a in applicationConfigs
join ga in groupApplicationConfigs
on new { a.ApplicationID, a.ConfigurationID } equals
new { ga.ApplicationID, ga.ConfigurationID }
select a;
Console.WriteLine(r);

Related

Linq Query to get latest of eact defect ID

In al_jira_defect_out table i have Batch_Insert_Timestamp, AL_Defect_ID columns along with other columns.And In this table there will be duplicate AL_Defect_IDs with different Batch_Insert_Timestamp.
As per below code in linq i am getting all records which are Jira_Status == 0
var defects = (from d in db.al_jira_defect_out
join p in db.al_jira_ref_defect_project on d.Defect_Product_ID.ToString() equals p.al_product_id
join t in db.al_jira_ref_defect_type on d.Defect_Type_ID equals t.type
where d.Jira_Status == 0
select new Issue
{
fields = new CreateIssue
{
project = new Project
{
key = g.jira_project_key
},
issuetype = new Issuetype()
{
name = t.jira_equivalent
},
description = d.Defect_ShortDesc,
summary = d.Defect_DetailDesc,
versions = new List<Versions>
{
new Versions {name = d.Defect_Release_DetectedIn}
},
priority = new Priority
{
name = d.Defect_Severity_Name
},
customfield_10182 = d.AL_Defect_ID.ToString(),
}
}).Select().ToList();
i am getting record with AL_Defect_IDs duplicate.
But i required latest records[Max(d.Batch_Insert_Timestamp)] of each d.AL_Defect_ID with all required columns
can any one please help me to get linq query
If you group on AL_Defect_IDs, you can order by Batch_Insert_Timestamp and take the last (latest) one:
var defects = (from d in db.al_jira_defect_out
join p in db.al_jira_ref_defect_project on d.Defect_Product_ID.ToString() equals p.al_product_id
join t in db.al_jira_ref_defect_type on d.Defect_Type_ID equals t.type
where d.Jira_Status == 0
group new { d, p, t } on d.AL_Defect_ID into dptg
let dpt = (from dpt in dptg order by dpt.d.Batch_Insert_Timestamp select dpt).Last()
select new // ... whatever using dpt
Your sample code doesn't use p in the select, so you could leave it out of the grouping.

many to many select list data

I would like to list the data with linq by combining the tables shown in the picture
expected result
using (CrmContext db = new Models.CrmContext())
{
_result = (from ct in db.CustomerDefination
join authorizedin db.authorized
on ct.customerId equals authorized.authorized
join authorizedDefination in db.authorizedDefination
on authorized.authorizedId equals authorizedDefination .authorizedId
select new
{
///I want to list the authorities belonging to
the customer
}).ToList();
}
There may be more than one authoritative definition of a customer. How can I do this in the LINQ query?
I spent WAY too much time doing your job, #IbrahimALPSOY:
Google Translating the turkish database screenshot,
Understanding which table holds what data using more Google Translate,
Understanding the expected result - which fields come from which tables,
Writing sample classes to represent the database,
Generating sample data for testing.
I wasted 30+ minutes before even starting to write a query. Next time I won't. Next time, you prepare your question such that, all other people could just copy your code and try queries right away.
This is the preparation:
class Authorisation
{
public int AuthorisationId; // yetkiliid
public int AccessId; // unvanid
public string AuthoriserName;
}
class Access
{
public int AccessId; // unvanid
public string AccessName;
}
class Customer
{
public int CustomerId; // musterid
public string CustomerName;
}
class Event
{
public int CustomerId;
public int AuthorisationId;
}
void Main()
{
var Customers = new[] {
new Customer() { CustomerId = 1, CustomerName = "Anne" },
new Customer() { CustomerId = 2, CustomerName = "Barbara" },
};
var Accesses = new[] {
new Access() { AccessId = 1, AccessName = "Read" },
new Access() { AccessId = 2, AccessName = "Write" },
};
var Authorisations = new[] {
new Authorisation() { AuthorisationId = 1, AuthoriserName = "The boss", AccessId = 1 }, // The boss can give read rights
new Authorisation() { AuthorisationId = 2, AuthoriserName = "The boss", AccessId = 2 }, // The boss can give write rights
new Authorisation() { AuthorisationId = 3, AuthoriserName = "A rookie", AccessId = 1 }, // A new employee can only give read rights
};
var Events = new[] {
new Event() { CustomerId = 1, AuthorisationId = 3 }, // A rookie let Anne read
new Event() { CustomerId = 1, AuthorisationId = 2 }, // While the boss let Anne write and scolded rookie
new Event() { CustomerId = 2, AuthorisationId = 1 }, // The boss thinks Barbara can't be trusted with write
};
}
I used this code instead of yours, because yours:
doesn't compile,
is illegible,
is badly formatted,
skips a table you've shown on your screenshot,
contains references to contexts only you have access to.
And here are the results:
Your query becomes feasible if you start with the table with non-unique keys:
from e in Events
join c in Customers on e.CustomerId equals c.CustomerId
join a in Authorisations on e.AuthorisationId equals a.AuthorisationId
join s in Accesses on a.AccessId equals s.AccessId
select new
{
e.CustomerId,
e.AuthorisationId,
c.CustomerName,
a.AuthoriserName,
s.AccessName
}
If this is not what you needed, modify my "preparation" to fit your question.

Convert SQL to lambda in C#

How can I re-write the following query from SQL to lambda in C#? Is it recommended to write in lambda?
SELECT *
FROM Claims
WHERE id IN (SELECT claimId
FROM MissingItems
GROUP BY claimId);
Equivalent using LINQ lambdas - assuming you have a collection of MissingItem objects in your code (and a representation of Claim in your code)
List<String> distinctClaimIds = missingItems.Select(mi => mi.claimId).Distinct();
List<Claim> claimsWithThoseIds = claims.Where(c => distinctClaimIds.Contains(c.id)).ToList();
Edit for your "one statement" interest:
Closest to "one statement" (even though I think 2 is more readable) I can think of:
List<Claim> claimsWithThoseIds = claims.Where(c => missingItems.Select(mi => mi.claimId).Distinct().Contains(c.id)).ToList()
You can use Join to do this in one "line":
class MissingItems
{
public string Id {get;set;}
}
class Claims
{
public string ClaimId {get;set;}
}
void Main()
{
List<MissingItems> mi = new List<MissingItems>() {
new MissingItems() {Id = "a"},
new MissingItems() {Id = "b"},
new MissingItems() {Id = "c"},
new MissingItems() {Id = "d"},
};
List<Claims> cl = new List<Claims>() {
new Claims() {ClaimId = "a"},
new Claims() {ClaimId = "f"},
new Claims() {ClaimId = "c"},
new Claims() {ClaimId = "d"},
};
var a = mi.Join(cl, m => m.Id, c => c.ClaimId, (m,c) => {
return new { Claim = c.ClaimId, Missing = m.Id};
});
foreach(var b in a)
{
Console.WriteLine("Claim: " + b.Claim + " Missing: " + b.Missing);
}
}
This will join the ClaimId from Claims on the MissingItems Id property. The output looks like this:
Claim: a Missing: a
Claim: c Missing: c
Claim: d Missing: d

How to write sub queries using Linq extension methods with EF 6

I'm new to linq and I have 3 tables with these columns.
Trainee (ID, TraineeName)
Course (ID, CourseName)
TraineeCourseEnrollment (TraineeID, CourseID, EnrolledDate)
I created a stored procedure to get un-enrolled courses using this query.
select *
from Course
where ID not in (select CourseID
from TraineeCourseEnrollment
where TraineeID = #traineeid);
How to write the corresponding linq query to this SQL query using extension methods?
You will have to do two queries, first to retrieve the IDs that you want to exclude and the second to get actual courses:
var excludeIDs = db.TraineeCourseEnrollments.Where(w => w.TraineeID == traineeid).Select(s => s.CourseID);
var courses = db.Courses.Where(w =>!excludeIDs.Contains(w.ID)).ToList();
Something like this:
Extensions methods:
int traineeid = ...;
var query = dc.Courses
.Where(c => ! dc.TraineeCourseEnrollments
.Where(o => o.TrainessID == traineeid)
.Select(o => o.CourseID)
.Contains(c.ID));
LINQ query:
int traineeid = ...;
var query =
from c in dc.Courses
where !(from o in dc.TraineeCourseEnrollments
where o.TraineeID == traineeid
select o.CourseID)
.Contains(c.ID)
select c;
var prospectus = new []
{
new { CourseId = "C1", CourseName = "Database" },
new { CourseId = "C2", CourseName = "HCI" },
new { CourseId = "C3", CourseName = "Op Systems" },
new { CourseId = "C4", CourseName = "Programming" }
};
var enrollment = new []
{
new { TraineeID = "T1", CourseId = "C1", Date = new DateTime(2014, 12, 01) },
new { TraineeID = "T2", CourseId = "C1", Date = new DateTime(2014, 12, 05) },
new { TraineeID = "T1", CourseId = "C3", Date = new DateTime(2014, 12, 01) }
};
var notMatchingQueryStyle = from c in prospectus
where !enrollment.Any(r => c.CourseId == r.CourseId)
select c;
Resharper nags me to "simplify" this using All instead of Any, go figure:
var notMatchingQueryStyle = from c in prospectus
where enrollment.All(r => c.CourseId != r.CourseId)
select c;

How to make linq master detail query for 0..n relationship?

Given a classic DB structure of Orders has zero or more OrderLines and OrderLine has exactly one Product, how do I write a LINQ query to express this?
The output would be
OrderNumber - OrderLine - Product Name
Order-1 null null // (this order has no lines)
Order-2 1 Red widget
I tried this query but is not getting the orders with no lines
var model = (from po in Orders
from line in po.OrderLines
select new
{
OrderNumber = po.Id,
OrderLine = line.LineNumber,
ProductName = line.Product.ProductDescription,
}
)
Here is an article which appears to explain how to achieve exactly what you are trying to do.
public static void OuterJoinSimpleExample()
{
var customers = new List<Customer>() {
new Customer {Key = 1, Name = "Gottshall" },
new Customer {Key = 2, Name = "Valdes" },
new Customer {Key = 3, Name = "Gauwain" },
new Customer {Key = 4, Name = "Deane" },
new Customer {Key = 5, Name = "Zeeman" }
};
var orders = new List<Order>() {
new Order {Key = 1, OrderNumber = "Order 1" },
new Order {Key = 1, OrderNumber = "Order 2" },
new Order {Key = 4, OrderNumber = "Order 3" },
new Order {Key = 4, OrderNumber = "Order 4" },
new Order {Key = 5, OrderNumber = "Order 5" },
};
var q = from c in customers
join o in orders on c.Key equals o.Key into outer
from o in outer.DefaultIfEmpty()
select new {
Name = c.Name,
OrderNumber = ((o == null) ? "(no orders)" : o.OrderNumber)
};
foreach (var i in q) {
Console.WriteLine("Customer: {0} Order Number: {1}",
i.Name.PadRight(11, ' '), i.OrderNumber);
}
Console.ReadLine();
}
This is the working query (built using the example linked above):
var model = (from po in orders
join line in orderLines // note this is another var, it isn't po.Lines
on po.Id equals line.OrderId into g
from line in g.DefaultIfEmpty()
select new
{
OrderNumber = po.Id,
OrderLine = line == null ? 0 : line.LineNumber,
ProductName = line == null ? string.Empty : line.Product.ProductDescription,
}
)
var model =
from po in Orders
from line in po.OrderLines.DefaultIfEmpty()
select new
{
OrderNumber = po.Id,
OrderLine = line != null ?
(int?)line.LineNumber : null,
ProductName = line != null ?
line.Product.ProductDescription : null
} ;

Categories

Resources