left join query in MVC - asp.net-mvc

I have added this code in my controller where I am left joining on 2 tables to stored result in lettergroup variable.
var lettergroup = (from e in opsdb.Queue2
join a in opsdb.QIncidents on e.QID equals a.QID into ps
from ad in ps.DefaultIfEmpty()
select new { ad.IncidentID, ad.TaxTypeID, ad.TaxPeriod, ad.StateID, ad.IncidentDate, e.CustomerID, e.DocumentID }).ToList();
I get this error:
The cast to value type 'System.Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
Please help me out with left join query in ASP.NET MVC

try this
var lettergroup = (from e in opsdb.Queue2
join a in opsdb.QIncidents on e.QID equals a.QID into ps
from a in ps.DefaultIfEmpty()
select new { IncidentId= a.IncidentID, TaxTypeID=a.TaxTypeID,
TaxPeriod= a.TaxPeriod, StateID= a.StateID, IncidentDate= a.IncidentDate,
CustomerID=e.CustomerID,DocumentID =e.DocumentID }).ToList();

Related

linq to entities decimal null values from outer join

LINQ giving an error while using the below linq
var data = (from p in _context.Products
from invp in _context.Inventories
.Where(inv=>inv.Product.ID== p.ID)
.DefaultIfEmpty()//left outer join
select new { p.ID, p.Name, p.BarCode, p.ProductCategory, p.MRP, p.RetailPrice,stock=invp.Stock } ).ToList() ;
The cast to value type System.Decimal failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
If I remove invp.stock from the select it is working , how can I default invp.stock to 0 if it is null.
You may select like this:
replace
stock=invp.Stock
with
stock=invp.Stock ?? 0
There is nullable decimal and we need to cast them then only it can take the database null to c#
Stock = (decimal?)invp.Stock

How to deal with Null Values in OUTER JOINS using Entity Framework 6

I need to process the query at the bottom of this post in C#. The query works, but I don't know how to use it in EF6. I used a method and a viewmodel for it (variable query = the query below). But when it encounters null values in the OUTER JOIN, int32 cant accept this value when calling .toList(). What's the best way to deal with it?
var result = context.Database.SqlQuery<TourQueryViewModel>(query);
var reslist = result.ToList();
I tried my first steps with LINQ, but I dont get it how to translate into LINQ itself or the query-methods, that are equivalent to it. So I am hoping for your help.
SELECT toursdata.TourId AS TourId, toursdata.Tourname AS Tourname,toursdata.Tourdate Tourdate,
toursdata.VehicleId AS VehicleId, toursdata.VehicleName AS VehicleName, toursdata.LicenseNumber AS LicenseNumber,
Employees.EmployeeId AS EmployeeId, Employees.Gender AS Gender, Employees.Forename AS Forename, Employees.Surname AS Surname
FROM (
SELECT te.TourId, te.Tourname, te.Tourdate,
Vehicles.VehicleId, Vehicles.VehicleName, Vehicles.LicenseNumber,
TourEmployees.EmployeeId
FROM TourEmployees RIGHT OUTER JOIN Tours AS te ON TourEmployees.TourId = te.TourId,
Tours AS tv INNER JOIN Vehicles ON tv.VehicleId = Vehicles.VehicleId
WHERE tv.TourId = te.TourId
) toursdata
LEFT OUTER JOIN Employees ON toursdata.EmployeeId = Employees.EmployeeId
To eliminate the null problem, I changed the data type of the corresponding entity-attribute to a nullable-type
int turned to int?.
Didnt know about that language feature.

EF4 Cascading Left Outer Joins Null Exception

I have this query
Select p.Name,p.Street from person p
left join address a on a.address_id = p.address_id
left join Order o on o.order_id = a.order_id
But when i try to convert it into LINQ query,
var q = from p in Entities.Person
from a in Entities.Address.Where(a=>a.address_id == p.address_id).DefaultIfEmpty()
from o in Entities.Order.Where (o=>o.order_id== a.order_Id).DefaultIfEmpty()
I am getting a Null exception since for some combination of address_ids there are no addresses and it blows up in o=>o.order_id== a.order_Id clause(since a is null).
Please let me know how to do multiple left joins in EF 4, the correct way !
Thanks !
If you have modeled correctly you do not need to explicitly do left outer joins.
Select p.Name, a.Street from person p
left join address a on a.address_id = p.address_id
left join Order o on o.order_id = a.order_id
The above query can be converted as follows
var projection = Entities.Person.Select(p => new {p.Name, p.Address.Street});
EF will automatically add the joins to retrieve the fields.
You can manually do the joins as follows
var projection = from p in Entities.Person
join a in Entities.Address on p.address_id equals a.address_id into outer
from a in outer.DefaultIfEmpty()
select new {p.Name, a.Street};

Convert Left outer join query into Entity Framework query

I have a sql statement that I want to be able to convert into EF4.
Its a simple Left outer join that looks like
SELECT *
FROM EntryDate
LEFT OUTER JOIN Member on Member.CardId = EntryDate.CardID
how do I do this using the entity framework 4?
If there is relation mapped in your model you can simply use navigation properties because they always use left join:
var data = members.EntryDates;
I expect you don't have such relation because CardId doesn't look like primary key of Member or EntryDate.
If you don't have navigation properties you must use
var query = from m in context.Members
join e in context.EntryDates on m.CardId equals e.CardId into x
from res in x.DefaultIfEmpty()
select new
{
Member = m,
EntryDate = res
};
This works only in EFv4+ because EFv1 didn't support DefaultIfEmpty.

Is my IQueryable syntax correct?

The generated SQL does a cross join but as the ID's are matched it acts like an inner join but is there a better performing way to do this by actually using the join keyword in C#? Is there a way where you don't have to specify how the properties join because they are all heirarchicly related anyway
Item is a Page class
PageRoles is an IQueryable property in a Page class
aspnet_Roles is an IQueryable property in a PageRole class
var item = _repository.GetByKey(999);
var f = (from fd in item.PageRoles
from k in fd.aspnet_Roles
where Roles.GetRolesForUser().Contains(k.RoleName)
&& k.RoleId == fd.RoleId
select k.RoleName)
.Count();
EDIT:
Here is an example of an IQueryable property in my classes. The below example comes from the PageRole class
public IQueryable<aspnet_Role> aspnet_Roles
{
get
{
var repo=NorthCadburyWebsite.Models.aspnet_Role.GetRepo();
return from items in repo.GetAll()
where items.RoleId == _RoleId
select items;
}
}
Does this compile or do you get an error?
In this case, as you mentioned, you don't need a join.
I haven't used this syntax, but it looks like you use k as a refererence (like an alias in sql syntax)
This should deliver the same result (without even using k):
var f = (from fd in item.PageRoles
where Roles.GetRolesForUser().Contains(fd.aspnet_Roles.RoleName)
&& fd.aspnet_Roles.RoleId == fd.RoleId
select fd.aspnet_Roles.RoleName)
.Count();
Note: Not tested, just a guess.
I don't have my Intellisense with me but I think you can:
var f = (from fd in item.PageRoles
join k in fd.aspnet_Roles on k.RoleId equals fd.RoleId
where Roles.GetRolesForUser().Contains(k.RoleName)
select k.RoleName)
.Count();
I think I'm confused, because I'm seeing the following hierarchy in your query which isn't making any sense:
[PageRoles]
|--RoleId <~~~~~~~~~.
|--[aspnet_Roles] |
|--RoleId ~~~~~~~*
|--RoleName
Is the hierarchy determined by the RoleId and you only mean for PageRoles.RoleId to reference aspnet_Roles.RoleId? So you might have something like:
[PageRoles] [aspnet_Roles]
|--RoleId |--RoleId
|--RoleName
And you're trying to make it into the following:
[PageRoles]
|--RoleId
|--[aspnet_Roles] (where RoleId == PageRoles.RoleId)
|--RoleName
...?
In which case if you can't do the following, then something is wrong with your IQueryable property definitions and not the query you have posted. Namely the method to get PageRoles's aspnet_Roles child rows is not set up properly.
var f = (from fd in item.PageRoles
from k in fd.aspnet_Roles
where Roles.GetRolesForUser().Contains(k.RoleName)
select k.RoleName)
.Count();
(fd.aspnet_Roles should already be constrained by RoleId and generate an inner join).
You can check your hierarchy by seeing what SQL is generated from:
var f = from fd in item.PageRoles
from k in fd.aspnet_Roles
select k;
which should vaguely resemble (with something having to do with item thrown in):
SELECT k.RoleName, k.SomethingElse
FROM PageRoles fd
INNER JOIN aspnetRoles k ON fd.RoleId = k.RoleId;
I'm sure I'm missing something, so please help me fill in the blanks...

Resources