How to Check for the nullable dates in the linq query - silverlight-4.0

I have a array of an object of type employee,
var s = from x in employee
where !string.IsNullOrEmpty(x.FirstName) && (x.FirstName.IndexOf(searchText, StringComparison.OrdinalIgnoreCase)) >= 0 || !string.IsNullOrEmpty(x.LastName) && (x.LastName.IndexOf(searchText, StringComparison.OrdinalIgnoreCase)) >= 0 ||
//I want to check here for null DateOfBirth
x.DateOfBirth.Value.ToShortDateString().StartsWith(searchText, StringComparison.OrdinalIgnoreCase)
select x;

I think all you need is
&& x.DateOfBirth.HasValue &&
Added into your where clause to filter out dobs that are null.
I'm assuming DateOfBirth is a nullable DateTime.

Related

Filter Data based on priority in LINQ

The fields in my Rate Table are Route, VehicleMasterId, VehicleType, Material, Client, UnitRate etc.
The priority order on which I have to fetch a single row is : VehicleNo > Route > Client > VehicleType, Material
Suppose I have 2 rows with same data except 1 has Client and Vehicle Type and the other one has VehicleNo.Then based on my priority, I should pick the rate of the row with VehicleNo.
To excute this In linq I have first picked all the rows with matching data. Here is my code.
public RateMasterDataModel GetRateMasterforCn(Consignment cn){
// I will always pass all the above fields in cn
var rateMaster = (from rate in Context.RateMaster
where rate.FromDate <= cn.Cndate
&& rate.ToDate >= cn.Cndate
&& (rate.VehicleTypeId != null ? rate.VehicleTypeId == cn.VehicleTypeId : true)
&& (rate.VehicleMasterId != null ? rate.VehicleMasterId == cn.VehicleMasterId : true)
&& (rate.ClientId != null ? rate.ClientId == cn.ClientId : true)
&& (rate.RouteId != null ? rate.RouteId == cn.RouteId : true)
&& (rate.MaterialMasterId != null ? rate.MaterialMasterId == cn.MaterialMasterId : true)
select new RateMasterDataModel
{
RateMasterId = rate.RateMasterId,
FromDate = rate.FromDate,
ToDate = rate.ToDate,
ClientId = rate.ClientId ,
VehicleMasterId = rate.VehicleMasterId,
VehicleTypeId = rate.VehicleTypeId,
MaterialMasterId = rate.MaterialMasterId,
UnitRate = rate.UnitRate,
LoadTypeId = rate.LoadTypeId,
LoadingPointId = rate.RouteId,
CalculationMasterId = rate.CalculationMasterId
}).ToList();
}
Please suggest how to filter after this.
You can use below code to get records ordered by VehicleNo > Route
.OrderBy(v=>v.VehicleNo).ThenBy(r=>r.RouteId)
Add multiple .ThenBy() clause as per your column requirement for sorting the data.
You mean to say if the row which doesn't have the vehicalno. filld-up then the row having Route must be selected.is it correct?

MVC SQL invalid

I have the following code in my MVC Index function. It is called from a search page that allows the user to search for various string values:
public ViewResult Index(string sortOrder, string YearString,string MonthString,string BudgetTypeString,string DescriptionString)
{
ViewBag.BudgetTypeSortParm = String.IsNullOrEmpty(sortOrder) ? "BudgetType_desc" : "";
ViewBag.MonthSortParm = sortOrder == "Date" ? "Month_desc" : "Month";
ViewBag.YearSortParm = sortOrder == "Date" ? "Year_desc" : "Year"; // 12-24-2014 JR added
ViewBag.DescriptionSortParm = sortOrder == "Description" ? "Description_desc" : "Description";
var budg = from s in db.budgets
select s;
if (!String.IsNullOrEmpty(YearString) ||
!String.IsNullOrEmpty(MonthString) ||
!String.IsNullOrEmpty(BudgetTypeString) ||
!String.IsNullOrEmpty(DescriptionString))
{
budg = budg.Where(s => s.BudgetType.ToUpper().Contains(BudgetTypeString.ToUpper()) ||
String.IsNullOrEmpty(BudgetTypeString) || s.Description.ToUpper().Contains(DescriptionString.ToUpper()) ||
String.IsNullOrEmpty(DescriptionString) ||
s.Month.ToUpper().Contains(MonthString.ToUpper()) ||
String.IsNullOrEmpty(MonthString) ||
s.Year.ToUpper().Contains(YearString.ToUpper()) ||
String.IsNullOrEmpty(YearString));
budg = budg.OrderBy(s => s.BudgetType);
return View(db.budgets.ToList());
}
}
Here is the actual SQL that is converted from the above code:
budg {SELECT
[Extent1].[id] AS [id],
[Extent1].[BudgetType] AS [BudgetType],
[Extent1].[Description] AS [Description],
[Extent1].[Amount] AS [Amount],
[Extent1].[Month] AS [Month],
[Extent1].[Year] AS [Year],
[Extent1].[DateStamp] AS [DateStamp]
FROM [dbo].[budget] AS [Extent1]
WHERE (( CAST(CHARINDEX(UPPER(#p__linq__0),
UPPER([Extent1].[BudgetType])) AS int)) > 0) OR
(( CAST(CHARINDEX(UPPER(#p__linq__1), UPPER([Extent1].[Description])) AS int)) > 0) OR
(( CAST(CHARINDEX(UPPER(#p__linq__2), UPPER([Extent1].[Month])) AS int)) > 0) OR
(( CAST(CHARINDEX(UPPER(#p__linq__3), UPPER([Extent1].[Year])) AS int)) > 0)}
Does anyone know why my strings are incorrectly being converted into integers and how to correct it so the search strings on my search page work correctly?
Let's take a look at just one of the Cast statements:
( CAST(CHARINDEX(UPPER(#p__linq__1), UPPER([Extent1].[Description])) AS int)) > 0)
Take a look at the inner statement. It's actually getting the CharIndex of one string in the other. Basically, does "Description" contain #p__linq__1. CharIndex returns 0 if if the first expression is not found in the other. The result of CharIndex is what is being Cast as int, and then compared to see if it is greater than 0. Which is exactly what you asked it to do when you use .Contains

Linq union all equivalent of sql code

I have the following queries:
var majorClients = maj in dbContext.MajorClients
where (maj.startdate > startDate)
where (maj.status == "Active")
Select new Client{EntityPK = maj.mjPrimaryKey,Name = maj.name, Type = "Maj"};
var minorClients = min in dbContext.MinorClients
where (min.startdate > startDate)
where (min.status == "Active" || min.status== "Inactive")
Select new Client{EntityPK = min.mnPrimaryKey,Name = min.name, Type = "Min"};
There are clients that could appear in both major and minor tables. I would like to return a list of all occurrences of clients in both tables, however if there are matching clients by name, then I would only want to return the matching record from the majorClients table.
I have written a sql query to return the results:
SELECT mjPrimaryKey AS EntityPK,name,'Maj' AS TYPE
FROM majorClients
WHERE status = 'Active' AND startDate > #startDate
UNION ALL
SELECT mnPrimaryKey,name,'Min' FROM minorClients
WHERE status IN ('Active','Inactive') AND startDate > #startDate
WHERE name NOT IN (SELECT name FROM majorClients WHERE status = 'Active' AND startDate > #startDate)
How would I represent this query in linq?
Try this linq. To exclude duplicates from minorClients, I've used Contains method. To union all objects - Union method:
var majorClients = from maj in dbContext.MajorClients
where maj.startdate > startDate
&& maj.status == "Active"
select new Client
{
EntityPK = maj.mjPrimaryKey,
Name = maj.name,
Type = "Maj"
};
var minorClients = from min in dbContext.MinorClients
where min.startdate > startDate
&& min.status == "Active" || min.status== "Inactive"
&& !(from maj in dbContext.MajorClients
where maj.startdate > startDate
&& maj.status == "Active"
select maj.name).Contains(min.Name)
select new Client
{
EntityPK = min.mnPrimaryKey,
Name = min.name,
Type = "Min"
};
var allClients = majorClients.Union(minorClients);

Linq to SQL combination of aggregate functions

Is there a way to simplify this and make it go faster?
In SQL I use count(*) and count(distinct) in same query which gives me a faster result
Thanks a bunch.
int numberOfUsers = (from u in db.UseLogs
where u.DocID == docID
&& u.LogDate >= fromDate
&& u.LogDate <= to
select u.UserID).Distinct().Count();
int numberOfVisits = (from u in db.UseLogs
where u.DocID == docID
&& u.LogDate >= fromDate
&& u.LogDate <= to
select u).Count();
Conclusion
There is no Count( Distinct) in LINQ. Not EVERY SQL statement can be translated into LINQ.
Thanks for the help guys!
Is this what you're looking for?
from u in db.UseLogs
where u.DocId == docId && u.LogDate >= fromDate && u.LogDate <= to
group u by true into g
select new
{
Count = g.Count(),
DistinctUserCount = g.Select(x => x.UserId).Distinct().Count()
}
You will want to check if it's actually faster than running two queries, or if the performance gain is worth the loss of readability.
Not exactly what you're trying to acheive but may be just as fast:
var query =
from u in db.UseLogs
where u.DocId == docId && u.LogDate >= fromDate && u.LogDate <= to
group u by u.UserID into g
select new
{
Visits = g.Count()
};
int numberOfUsers = query.Count();
int numberOfVisits = query.Sum(q=>q.Visits);
It executes the SQL only once and does the SUMming in memory.

LINQ to NHibernate WHERE EXISTS IN

I've been trying out NHibernate 3 and LINQ to NHibernate. I can't get it to spit out the correct T-SQL query.
Here's my domain model:
Employee { id, name }
Department { id, name }
EmployeeDepartment { id, employee_id, department_id, startdate, enddate }
AttendanceRegistration { id, datetime, employee_id }
Now suppose I'd like to select all AttendanceRegistrations between '2010-10-1' and '2010-11-1' that were connected to a certain department at that time.
DateTime start = new DateTime(2010,10,1);
DateTime end = new DateTime(2010,11,1);
var list =
from ar in session.Query<AttendanceRegistration>()
where
start <= ar.datetime && ar.datetime > end && (
from ed in session.Query<EmployeeDepartment>()
where
ed.startdate <= ar.datetime && ed.enddate > ar.datetime &&
ed.department_id = 1
select ed.employee_id
).Contains(ar.employee_id)
select ar;
The resulting SQL Code will look like this:
select ar.id, ar.datetime, ar.employee_id
from AttendanceRegistration ar
where
'2010-10-1 00:00:00' <= ar.datetime and '2010-11-1' > ar.datetime and exists (
select ed.employee_id
from EmployeeDepartment ed
where
ed.department_id=1 and
ed.startdate <= ar.datetime and
ed.enddate > ar.datetime and
ed.id=ar.employee_id
)
This is ALMOST good :-) The only mistake is
ed.id=ar.employee_id
This should have been:
ed.employee_id=ar.employee_id
Does anybody have ideas how to get LINQ to NHibernate spit out the correct T-SQL query?
I ran into the same problem. I found a way to get around this. Your query can be rewritten as follows. Basically instead of using Contains() operator, add your predicate explicitly in the where clause and use Any() operator.
DateTime start = new DateTime(2010,10,1);
DateTime end = new DateTime(2010,11,1);
var list =
from ar in session.Query<AttendanceRegistration>()
where
start <= ar.datetime && ar.datetime > end && (
from ed in session.Query<EmployeeDepartment>()
where
ed.startdate <= ar.datetime && ed.enddate > ar.datetime &&
ed.department_id == 1
&& ed.employee_id == ar.employee_id
select ed
).Any()
select ar;