I am having trouble converting a SQL Join statement into LINQ to DataSet. Also, consider that there will be other tables in the LINQ statement that the Header table will be joined to. Below is my Join statement - any help is appreciated.
FROM Header
LEFT JOIN Address
ON Header.Customer = Address.Customer
AND Header.Company = Address.Company
AND ((Header.ShipTo = 'TEMP' AND Header.DocNum = Address.ShipTo)
OR Header.ShipTo <> 'TEMP' AND Header.ShipTo = Address.ShipTo)
Doing a join in Linq uses the Equals() method. When using multiple columns, you'll have to create an identically structured anonymous type for comparison.
from h in db.header
join a in db.address
on new {
cust = h.Customer,
comp = h.Company
}
equals new
{
cust = a.Customer,
comp = a.Company
}
where ((h.ShipTo == "TEMP" && h.DocNum == a.ShipTo)
|| h.ShipTo != "TEMP" && h.ShipTo == a.ShipTo)
select h;
Related
I have a code that selecting from table and joining multiple tables and joining dbContext.Database.sqlQuery from view in sql server.
But it gives me this error
Unable to create a constant value of type
'ITManagement.Models.Employee'. Only primitive types or enumeration
types are supported in this context.
My code
public JsonResult getEmployeeAsset(EmployeeController employee)
{
var employeeID = Request.QueryString["employeeID"];
var devices = (from asset in db.Devices
where asset.EmployeeID == employeeID
join brand in db.DeviceBrands on asset.Brand equals brand.ID
join model in db.DeviceModels on asset.Model equals model.ID
join type in db.DeviceTypes on asset.DeviceType equals type.ID
join room in db.Rooms on asset.FullRoomCode equals room.FullCode
//if device has last employee
join lsEmp in db.Database.SqlQuery<LDAPUsers>("SELECT * FROM V_LDAP_Users") on asset.LastEmployeeID equals lsEmp.employeeID into lstEmp
join sysUser in db.AspNetUsers on asset.sscUser equals sysUser.Id
from lastEmployee in lstEmp.DefaultIfEmpty()
select new
{
deviceID = asset.ID,
SerialNumber = asset.SerialNumber,
Type = type.Type,
BrandName = brand.BrandName,
ModelName = model.ModelName,
MaccCode = asset.MaccCode,
PONumber = asset.PONumber,
WarrantyDate = asset.WarrantyDate.ToString(),
MacAddress = asset.MacAddress,
WIFIMacAddress = asset.WIFIMacAddress,
PCName = asset.PCName,
LastEmployee = asset.LastEmployeeID + "-" + lastEmployee.employeeName,
Shared = asset.Shared == 1 ? "True" : "False",
Location = room.RoomName,
RecordedBy = sysUser.Name,
requestID = (from request in db.StoreRequests where request.DeviceID == asset.ID && request.State == 1 && request.VoucherType == "ASD" orderby request.ID select request.ID).FirstOrDefault()
}).DefaultIfEmpty();
return Json(new { assets = devices == null ? null : devices }, JsonRequestBehavior.AllowGet);
}
Your help please, thanks.
First of all, have you tried nested queries by commenting them out?
for example;
//join lsEmp in db.Database.SqlQuery<LDAPUsers>("SELECT * FROM V_LDAP_Users") on asset.LastEmployeeID equals lsEmp.employeeID into lstEmp
//requestID = (from request in db.StoreRequests where request.DeviceID == asset.ID && request.State == 1 && request.VoucherType == "ASD" orderby request.ID select request.ID).FirstOrDefault()
If there is no problem in these two, you can quickly find out which one is causing the problem by commenting the fields.
Tip: Also, more than 3 joins will affect your query performance. Try to split your queries as much as possible.
I'm using Telerik Open Access. I have two separate projects that have Open Access data and then a third project that has the bulk of my code. I've been working on a way to convert a simple (at least I thought it was) SQL query to LINQ so that I can get the data I need. I have not been successful. I've had to break a single LINQ query into separate queries, because of the need for the Trim() function (I think). This has led to a lengthy piece of code and I'm still not getting the same results as my SQL query.
So my question is, is there anyway to use SQL instead of LINQ to access the data in the Open Access projects? If so, can you show me the syntax to do that for my query?
If it is not possible to use SQL, can you show me show me the proper way to convert my SQL query into LINQ so that I get the same results?
Thank you.
My SQL query is
SELECT DISTINCT us2.ccustno, us2.dispname, us2.csiteno, so.s1_name
FROM [DALubeDeacom].[dbo].[dmbill] bi
INNER JOIN [DALubeDeacom].[dbo].[dmso1] so
ON bi.bi_s1id = so.s1_id
INNER JOIN [DALubeNew].[dbo].[usersecurity] us2
ON so.s1_name = us2.cparentno
WHERE
us2.ctype = 'JOBSITE'
AND us2.csiteno is not null
AND us2.csiteno != ''
AND bi.bi_smid = '22'
ORDER BY us2.csiteno
My LINQ query is
public List<DataModelSample> GetLocationsBySalesNo(string salesNo)
{
int iSalesNo = int.Parse(salesNo.Trim());
try
{
var dmso = (
from so in deacom.Dmso1
join qt in deacom.Dmbills
on so.S1_id equals qt.Bi_s1id
where qt.Bi_smid == iSalesNo
select new Dmso1
{
S1_id = so.S1_id
, S1_name = so.S1_name.Trim()
}
);
var usec = (
from us in dbContext.Usersecurities
where us.Cparentno != null && us.Cparentno.Trim() != "" && us.Ctype.Trim() == "JOBSITE" && us.Csiteno.Trim() != ""
select new Usersecurity
{
Ccustno = us.Ccustno.Trim(),
Csiteno = us.Csiteno.Trim(),
Dispname = us.Dispname.Trim(),
Cparentno = us.Cparentno.Trim()
}
);
var customers =
(
from us in usec
join so in dmso
on us.Cparentno equals so.S1_name
select us
);
customers = customers.GroupBy(x => x.Csiteno).Select(x => x.First());
List<DataModelSample> listLocations =
(
from c in customers
select new DataModelSample
{
customerID = c.Ccustno
,
origLocationName = c.Csiteno + " " + c.Dispname
,
origLocationID = c.Csiteno
}
).OrderBy(x => x.origLocationID).ToList();
return listLocations.ToList();
}
catch (Exception ex)
{
throw ex;
}
} // GetLocationsBySalesNo(userInfo.csalesno)
Edit 1 - 2-19-16
Tried a suggestion by ViktorZ. His query was similar to the one I first tried. It returned the error "Identifier 'Ctype' is not a parameter or variable or field of 'DALube_DeacomModel.Dmbill'. If 'Ctype' is a property please add the FieldAlias or Storage attribute to it or declare it as a field's alias." From an online search, it looked like this was do to "extended fields". I don't seemed to be using such fields. The only way I could get around this error was to break it into the smaller LINQ queries in my original question, which didn't produce the right results. Any suggestions?
Here's the code:
var query = (from bill in deacom.Dmbills
join so in deacom.Dmso1 on bill.Bi_s1id equals so.S1_id
join us in dbContext.Usersecurities on so.S1_name equals us.Cparentno
where us.Ctype == "JOBSITE"
&& us.Csiteno != null
&& us.Csiteno != string.Empty
&& bill.Bi_smid == iSalesNo
select new
{
ccustno = us.Ccustno.Trim(),
dispname = us.Dispname.Trim(),
csiteno = us.Csiteno.Trim(),
s1_name = so.S1_name.Trim()
}).Distinct();
One very crude approximation of your SQL query is:
var query = (from bill in deacom.Bills
join so in deacom.LubeDeacom on bill.bi_s1id equals so.s1_id
join us in deacom.UserSecurity on so.s1_name equals us.cparentno
where us.ctype = "JOBSITE"
&& us.csiteno != null
&& us.csiteno != string.Empty
&& bill.smid = '22'
order by us.csiteno
select new
{
us.ccustno.Trim(),
us.dispname.Trim(),
us.csiteno.Trim(),
so.s1_name.Trim()
}).Distinct();
// to check the translation result
string sql = query.ToString()
// to get the results
var result = query.ToList()
If this is not working for you, you can always fall back to Telerik Data Access ADO.NET API. Here is a documentation article how to use it.
i am tying to join multiple columns. There is no problem if column type int or string etc.. but my columns types are smallint.
query:
var getworks = (from loc in db.T_location
join wl in db.T_vehicle_work_list
on new {x=loc.Route_id, y=loc.Cash_center_num}
equals new { x=wl.Route_id, y=wl.Cash_center_num}
where wl.Route_id == getVehicleRouteId.Route_id && wl.Cash_center_num == getVehicleRouteId.Cash_center_num
&& wl.Status_code != "C"
&& wl.Instance_id > bfd
&& wl.Instance_id < afd
select new { loc, wl }).ToList();
error : "The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'."
thanx for help...
If anybody have this problem too. Check the model.edmx column "nullable" properties are same
I just want the apartment complex count along with the other values. Only adding the count breaks the code. The error I get is "Sequence operators not supported for type 'System.String'." I have also tried changing apartCount to an int with no luck. Any help would be appreciated
using (var db = new DataClasses2DataContext())
{
var zips = (from s in db.ZipCodeServiceAvailabilities
join b in db.ZipCodeBoundaries on s.ZipCode equals b.ZipCode
join a in db.pdx_apart_views on s.ZipCode equals a.Zip_Code
where (s.IsServiced == 1 && b.Ordering % 10 == 0)
orderby b.ZipCode
select new
{
zipCode = b.ZipCode.Trim(),
latitude = b.Latitude,
longitude = b.Longitude,
apartCount = a.Apartment_complex.Count()
}).ToArray();
}
I think you miss group by clause in your query.
or you can use corolated sub query in select clause. please explain your question more
HI,
I have a scenario where i have join multiple table and get the output in DataRow(All the Rows return by the query).
SQL Query:
SELECT Fr.InterCodeId
FROM
CodeShareInterline Fr,
Airline A,Zone Z #
WHERE
A.AirlineId = Fr.AirlineId
And Fr.ContractId=Z.ContractId
I know how to perform join in LINQ but how can i select all the column(Rows) in select statement of LINQ.
var result = from fr in dataContext.CodeShareInterline
from a in dataContext.AirLine
from z in dataContext.Zone
where a.AirlineId == fr.AirlineId && fr.ContractId == z.ContractId
select new
{
Interline = fr,
AirLine = a,
Zone = z
};
The anonymous type contains all data you want, you can easily visit one column by:
result.FirstOrDefault().Zone.SomeField
This is untested but something close to this should work. Assuming your data context is call Context. This is a translation of what you have above.
var o = from fr in Context.CodeShareInterline
join a from Context.Airline on a.AirlineId == fr.AirlineId
join z from Context.Zone on fr.ContactId == z.ContactId
select fr.InterCodeId;
If you want to select all of the data then you need to do something like this.
var o = from fr in Context.CodeShareInterline
join a from Context.Airline on a.AirlineId == fr.AirlineId
join z from Context.Zone on fr.ContactId == z.ContactId
select new {
Interline = fr,
AirLine = a,
Zone = z
};