How to format data value - linq

I have the following Linq to Sql:
var subscribers = (from s in dataContext.Employees
where s.RowType == "Edit"
select new SubscriberExportData
{
ID = s.ID.ToString(),
GroupNum = s.GroupNumber,
DivisionNum = s.DivisionNumber,
HireDate = s.HireDate != null ? Convert.ToDateTime(s.HireDate).ToShortDateString() : string.Empty,
EffDate = s.EffectiveDate != null ? Convert.ToDateTime(s.EffectiveDate).ToShortDateString() : string.Empty
}
Essentially, if the date value is not null then convert them to short date format. But I am getting the following error:
System.InvalidOperationException was unhandled
Message=Could not translate expression 'Table(Employee).Where(s => (s.RowType == "Edit")).Select(s => new SubscriberExportData() { HireDate = IIF((s.HireDate != null), ToDateTime(Convert(s.HireDate)).ToShortDateString(), Invoke(value(System.Func`1[System.String]))), EffDate = IIF((s.EffectiveDate != null), ToDateTime(Convert(s.EffectiveDate)).ToShortDateString)' into SQL and could not treat it as a local expression.
Source=System.Data.Linq
Please let me know how to resolve it.

You can split the query into two, the first being operations that sql understands and the second being the string conversions that will be performed locally
var list = (from s in dataContext.Employees
where s.RowType == "Edit"
select new
{
s.ID
s.GroupNumber,
s.DivisionNumber,
s.HireDate
s.EffectiveDate
}).ToList();
var subscribers = (from s in list
select new SubscriberExportData
{
ID = s.ID.ToString(),
GroupNum = s.GroupNumber,
DivisionNum = s.DivisionNumber,
HireDate = s.HireDate != null ? Convert.ToDateTime(s.HireDate).ToShortDateString() : string.Empty,
EffDate = s.EffectiveDate != null ? Convert.ToDateTime(s.EffectiveDate).ToShortDateString() : string.Empty
}

Related

how to pass string variable to linq select new {} section

Ii just want to make search functionality with linq with multiple ColumnNames that stored to session variable. I'm using one method:
public void FillGrid(string CommandName,string ColumnName, string SearchText)
That has three string variable that stores session value.
Now I just want to pass ColumnName with this query:
var query1 = (from p in db.Posts
join c in db.Categories on p.Category_id equals c.Id
join u in db.Users on p.User_id equals u.Id
where (p.ToUser_id == user_id || p.ToUser_id == null) && p.User_id != user_id
orderby p.Sent_Datetime descending
select new
{
Id = p.Id,
Title = p.Title,
Publisher = u.First_name + " " + u.Last_name,
ToUser = p.ToUser_id,
PublishDate = p.Sent_Datetime,
IsFile = p.IsFileAttached,
CategoryName = c.Category_name,
status_name = (from s in db.Status where (s.Id == p.status_id) select s.status_name).FirstOrDefault(),
Group_name = (from g in db.Groups where (g.Id == p.group_id) select g.Group_name).FirstOrDefault(),
FileSize = p.TotalFileSize,
ColumnName = Sesssion["ColumnName"].ToString()
}).Where(q => q.ColumnName.Contains(SearchText));
However, ColumnName does not give any text or it may be not part of this query i have to manually give column name because.
for multiple column i have, so i can not use this statement like:
.Where(q => q.Tile.Contains(SearchText));
this query works fine with single column. but there is multiple column i have so i have to set q.ColumnName from outer side.
I would do an extension method for that kind of things, building an expression for your predicate.
public static class Helper
{
public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
{
if (colName != null && searchText != null)
{
var parameter = Expression.Parameter(typeof(T), "m");
var propertyExpression = Expression.Property(parameter, colName);
var searchExpression = Expression.Constant(searchText);
var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var body = Expression.Call(propertyExpression, containsMethod, searchExpression);
var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
return queryable.Where(predicate);
}
else
{
return queryable;
}
}
}
usage in your case
var query1 = (from p in db.Posts
join c in db.Categories on p.Category_id equals c.Id
join u in db.Users on p.User_id equals u.Id
where (p.ToUser_id == user_id || p.ToUser_id == null) && p.User_id != user_id
orderby p.Sent_Datetime descending
select new
{
Id = p.Id,
Title = p.Title,
Publisher = u.First_name + " " + u.Last_name,
ToUser = p.ToUser_id,
PublishDate = p.Sent_Datetime,
IsFile = p.IsFileAttached,
CategoryName = c.Category_name,
status_name = (from s in db.Status where (s.Id == p.status_id) select s.status_name).FirstOrDefault(),
Group_name = (from g in db.Groups where (g.Id == p.group_id) select g.Group_name).FirstOrDefault(),
FileSize = p.TotalFileSize,
}).FilterForColumn(Sesssion["ColumnName"].ToString(), SearchText);

NotSupportedException The entity or complex type cannot constructed in a LINQ to Entity query ASP.Net MVC 3

This is the first time i encountered this error .
can someone help me?
public IEnumerable<APPLICANT> GetApplicant()
{
IEnumerable<APPLICANT> applicantdata = Cache.Get("applicants") as IEnumerable<APPLICANT>;
IEnumerable<Profile> profiledata = Cache.Get("profiles") as IEnumerable<Profile>;
if (applicantdata == null)
{
var list = (from f in context.APPLICANTs
select f.APPLICANT_ID).ToList();
var applicantList = (from a in context.Profiles
join app in context.APPLICANTs on a.PROFILE_ID equals app.Profile_id
where list.Contains(app.APPLICANT_ID)
select new APPLICANT());
applicantdata = applicantList.Where(v => v.APPLICANT_LastName != null && v.APPLICANT_LastName != "" ).OrderBy(v => v.APPLICANT_ID).ToList();
if (applicantdata.Any())
{
Cache.Set("applicants", applicantdata, 30);
}
}
And im Having Error in this line
applicantdata = applicantList.Where(v => v.APPLICANT_LastName != null && v.APPLICANT_LastName != "" ).OrderBy(v => v.APPLICANT_ID).ToList();
Thanks if someone will help
change
var applicantList = (from a in context.Profiles
join app in context.APPLICANTs on a.PROFILE_ID equals app.Profile_id
where list.Contains(app.APPLICANT_ID)
select new APPLICANT());
to
var applicantList = (from a in context.Profiles
join app in context.APPLICANTs on a.PROFILE_ID equals app.Profile_id
where list.Contains(app.APPLICANT_ID)
select app);
if you create new APPLICANT() you have newly created applicants without any data
and also applicantList.Where(v => v.APPLICANT_LastName != null && v.APPLICANT_LastName != "" )
can change to
applicantList.Where(v => !String.IsNullOrEmpty(v.APPLICANT_LastName))

LINQ join issue, returns all null value

I am new in EF and LINQ and I am facing a strange issue. When I check null value in my select new block, all values from child table is coming null. Below is the LINQ query.
My Linq Code
var linqResult = from pd in entities.tblpackagedetails
join ps in entities.tblpackageselecteds
on pd.PackageDetailsID equals ps.PackageDetailsID
into tabJoin
from tj in tabJoin.Where(ps => ps.UserID == userID
&& ps.IsActive == true).DefaultIfEmpty()
select new
{
IsComplete = (tj == null) ? false : tj.IsComplete,
IsActive = (tj == null) ? false : tj.IsActive,
UserID = (tj == null) ? 0 : tj.UserID,
IsMandatory = pd.IsMandatory,
PackageSelectedID = (tj == null) ? 0 : tj.PackageSelectedID,
IsSelected = (tj == null ? false : tj.IsSelected),
pd.Amount,
pd.Code,
pd.Description,
pd.Points,
pd.PackageDetailsID
};
foreach (var result in linqResult)
{
packagesSelected.Add(new PackageDetailDataModel()
{
Amount = result.Amount,
Code = result.Code,
Description = result.Description,
IsComplete = result.IsComplete,
IsMandatory = result.IsMandatory,
PackageDetailsID = result.PackageDetailsID,
PackageSelectedID = result.PackageSelectedID,
Points = result.Points,
IsActive = result.IsActive,
UserID = result.UserID,
IsSelected = result.IsSelected
});
}
SQL generated by Visualizer
SELECT
`Extent1`.`PackageDetailsID`,
`Extent2`.`IsComplete`,
`Extent2`.`IsActive`,
`Extent2`.`UserID`,
`Extent1`.`IsMandatory`,
`Extent2`.`PackageSelectedID`,
`Extent2`.`IsSelected`,
`Extent1`.`Amount`,
`Extent1`.`Code`,
`Extent1`.`Description`,
`Extent1`.`Points`
FROM `tblpackagedetails` AS `Extent1`
LEFT OUTER JOIN `tblpackageselected` AS `Extent2`
ON (`Extent1`.`PackageDetailsID` = `Extent2`.`PackageDetailsID`)
AND ((`Extent2`.`UserID` = #linq_0) AND (1 = `Extent2`.`IsActive`))
When I ran above sql in MySQL workbench I got below output (repalcing #linq_0 with userID).
My Parent Table Structure
Child Table Structure
Output I want
But the values for IsComplete, IsActive, UserID, PackageSelectedID and IsSelected null as a result condition checking in select new block assign false or 0.
If I remove null checking, I get value for first 3 rows and in fourth iteration I get below exception.
The cast to value type 'Boolean' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type
Please help... :(
Working code block
packagesSelected = new List<PackageDetailDataModel>();
var linqResult = from pd in entities.tblpackagedetails
join ps in entities.tblpackageselecteds
on pd.PackageDetailsID equals ps.PackageDetailsID
into tabJoin
from tj in tabJoin.Where(ps => ps.UserID == userID
&& ps.IsActive == true).DefaultIfEmpty()
select new
{
IsComplete = (bool?)tj.IsComplete,
IsActive = (bool?)tj.IsActive,
UserID = (int?)tj.UserID,
IsMandatory = pd.IsMandatory,
PackageSelectedID = (int?)tj.PackageSelectedID,
IsSelected = (bool?)tj.IsSelected,
pd.Amount,
pd.Code,
pd.Description,
pd.Points,
pd.PackageDetailsID
};
foreach (var result in linqResult)
{
packagesSelected.Add(new PackageDetailDataModel()
{
Amount = result.Amount,
Code = result.Code,
Description = result.Description,
IsComplete = (result.IsComplete ?? false),
IsMandatory = result.IsMandatory,
PackageDetailsID = result.PackageDetailsID,
PackageSelectedID = (result.PackageSelectedID ?? 0),
Points = result.Points,
IsActive = (result.IsActive ?? false),
UserID = (result.UserID ?? 0),
IsSelected = (result.IsSelected ?? false)
});
}
Thanks to 2Kay :)
When tj is null, EF consieders all properties of tj as null. It's ok, but when EF trying to materialize them into value-types it fails. So the solution is to use nullable types..
Try this query:
var linqResult = from pd in entities.tblpackagedetails
join ps in entities.tblpackageselecteds
on pd.PackageDetailsID equals ps.PackageDetailsID
into tabJoin
from tj in tabJoin.Where(ps => ps.UserID == userID
&& ps.IsActive == true).DefaultIfEmpty()
select new
{
IsComplete = (bool?) tj.IsComplete,
IsActive = (bool?) tj.IsActive,
UserID = (int?) tj.UserID,
IsMandatory = pd.IsMandatory,
PackageSelectedID = (int?) tj.PackageSelectedID,
IsSelected = (bool?) tj.IsSelected,
pd.Amount,
pd.Code,
pd.Description,
pd.Points,
pd.PackageDetailsID
};

Linq: Nested queries are better than joins, but what if you use 2 nested queries?

In her book Entity Framework Julie Lerman recommends using nested queries in preference to joins (scroll back a couple of pages).
In her example see populates 1 field this way, but what id you want to populate 2?
I have an example here where I would prefer to populate the Forename and Surname with the same nested query rather than 2 separate ones. I just need to know the correct syntax to do this.
public static List<RequestInfo> GetRequests(int _employeeId)
{
using (SHPContainerEntities db = new SHPContainerEntities())
{
return db.AnnualLeaveBookeds
.Where(x => x.NextApproverId == _employeeId ||
(x.ApproverId == _employeeId && x.ApprovalDate.HasValue == false))
.Select(y => new RequestInfo
{
AnnualLeaveDate = y.AnnualLeaveDate,
Forename = (
from e in db.Employees
where e.EmployeeId == y.EmployeeId
select e.Forename).FirstOrDefault(),
Surname = (
from e in db.Employees
where e.EmployeeId == y.EmployeeId
select e.Surname).FirstOrDefault(),
RequestDate = y.RequestDate,
CancelRequestDate = y.CancelRequestDate,
ApproveFlag = false,
RejectFlag = false,
Reason = string.Empty
})
.OrderBy(x => x.AnnualLeaveDate)
.ToList();
}
}
There's nothing wrong with your query, but you can write it in a way that is much simpler, without the nested queries:
public static List<RequestInfo> GetRequests(int employeeId)
{
using (SHPContainerEntities db = new SHPContainerEntities())
{
return (
from x in db.AnnualLeaveBookeds
where x.NextApproverId == employeeId ||
(x.ApproverId == employeeId && x.ApprovalDate == null)
orderby x.AnnualLeaveDate
select new RequestInfo
{
AnnualLeaveDate = x.AnnualLeaveDate,
Forename = x.Employee.Forename,
Surname = x.Employee.Surname,
RequestDate = x.RequestDate,
CancelRequestDate = x.CancelRequestDate,
ApproveFlag = false,
RejectFlag = false,
Reason = string.Empty
}).ToList();
}
}
See how I just removed your from e in db.Employees where ... select e.Forename) and simply replaced it with x.Employee.Forename. When your database contains the correct foreign key relationships, the EF designer will successfully generate a model that contain an Employee property on the AnnualLeaveBooked entity. Writing the query like this makes it much more readable.
I hope this helps.
try this
using (SHPContainerEntities db = new SHPContainerEntities())
{
return db.AnnualLeaveBookeds
.Where(x => x.NextApproverId == _employeeId ||
(x.ApproverId == _employeeId && x.ApprovalDate.HasValue == false))
.Select(y =>
{
var emp = db.Emplyees.Where(e => e.EmployeeId == y.EmployeeId);
return new RequestInfo
{
AnnualLeaveDate = y.AnnualLeaveDate,
Forename = emp.Forename,
Surname = emp.Surname,
RequestDate = y.RequestDate,
CancelRequestDate = y.CancelRequestDate,
ApproveFlag = false,
RejectFlag = false,
Reason = string.Empty
};
).OrderBy(x => x.AnnualLeaveDate).ToList();
}

How to make this LINQ To entity method work when it has Nullable LEFT JOIN

Here is the code snippet, actually the whole method. This method works f,ine when NULLAblE Foreign Key Refernces has value. When the value is not there, then this method does not work. My idea is to get all the records even if the references column is NULL. Here is the code :
public List<PostedJob> GetPostedJobs(int startingIndex, int maximumRows)
{
using (var records = new CommonEvent())
{
var resultSet =
from r in records.ProjectPosts
join rr in records.Categories on r.Category_FK equals rr.ID
join al in records.ApplyForLimits on r.ApplyForLimit_FK
equals al.Id
//from uImage in
// records.UploadedFiles
// .Where(uu=>uu.Id == r.UploadedFileInfo_FK
// || r.UploadedFileInfo_FK == null).DefaultIfEmpty()
join a in records.UploadedFiles on r.UploadedFileInfo_FK
equals a.Id into something
from uImage in something.DefaultIfEmpty()
orderby r.PostId
select new Models.PostedJob
{
ApplyForLimitName = al.Name,
ProjectTitle = r.ProjectTitle,
ProjectDescription = r.ProjectDescription,
ProjectSummaryDescription = r.ProjectSummaryDescription,
SkillsRequirements = r.SkillsRequirements,
CategoryName = rr.CategoryName,
UploadedFileID = (int) r.UploadedFileInfo_FK,
UploadedFileInformation = uImage == null ?
new Models.UploadedFile
{
fileContents = new byte [] { (byte) 0},
FileExtension = string.Empty,
FileName = string.Empty,
FileSize = 0,
UploadedDate = DateTime.Now
}
:
new Models.UploadedFile
{
fileContents = uImage.FileContents,
FileExtension = uImage.FileExtension,
FileName = uImage.FileName,
FileSize = uImage.FileSize,
UploadedDate = DateTime.Now
}
};
return resultSet.Skip(startingIndex).Take(maximumRows).ToList();
}
Thank you for any suggestions or ideas on how to proceed . I am using .NET 4.0
Can you not use the Associations generated for you?
var a = records
.ProjectPosts
.Select(
projectPost =>
new Models.PostedJob()
{
ProjectTitle = projectPost.ProjectTitle,
CategoryName = projectPost.Category.CategoryName,
});
Something along those lines?
EDIT: And just add Null checks when the FK may fail
example:
CategoryName = projectPost.Category == null ? String.Empty : projectPost.Category.CategoryName,

Resources