How to refactor LINQ query - c#

I have the following code:
result = from i in _dbContext.Meetings
where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && //!i.IsTex &&
DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
//where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
{
Name = i.UserInviter.FirstName + " " + i.UserInviter.LastName,
Company = i.UserInviter.Company,
Company2 = i.UserInvited.Company,
MeetingID = i.MeetingID,
Time = DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value,
CreatedTime = i.dateCreated,
Image = i.UserInviter.ProfileImage,
TableNumber = i.TableNumber,
Username = i.UserInviter.aspnet_User.UserName,
Username2 = i.UserInvited.aspnet_User.UserName,
UsernameInviter = i.UserInviter.aspnet_User.UserName,
RequestText = i.RequestText,
NoteInviter = i.NoteInviter,
ResendInvitationCount = (i.ResendInvitationCount.HasValue) ? i.ResendInvitationCount.Value : 0,
NoteInvited = i.NoteInvited,
MeetingType = i.MeetingType.TypeName
};
I use many such extentions with different modifications, but each of them has the same part select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp().....
i.e.
result = from i in _dbContext.Meetings
where i.UserInviterID == CurrentUserID && i.MeetingStatus == null && !i.IsTex && DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
//where i.UserInviterID == CurrentUserID && i.MeetingStatus == null && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
{
Name = i.UserInvited.FirstName + " " + i.UserInvited.LastName,
//...
};
result = from i in _dbContext.Meetings
where (i.UserInviterID == CurrentUserID) && i.MeetingStatus == true && !i.IsTex && DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
//where (i.UserInviterID == CurrentUserID) && i.MeetingStatus == true && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
select new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
{
Name = i.UserInvited.FirstName + " " + i.UserInvited.LastName,
//...
};
Can I set this part to variable to use in all other extentions?

You'll need to give up on the LINQ query syntax, and call the Select method directly. That should be no big deal. If you do that, you can store the projection part of your query in a separate variable.
Expression<Func<Meeting, ITW2012Mobile.Core.DataTable.MeetingModel2Tmp>> projection = i =>
new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp()
{
Name = i.UserInviter.FirstName + " " + i.UserInviter.LastName,
Company = i.UserInviter.Company,
Company2 = i.UserInvited.Company,
MeetingID = i.MeetingID,
Time = DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value,
CreatedTime = i.dateCreated,
Image = i.UserInviter.ProfileImage,
TableNumber = i.TableNumber,
Username = i.UserInviter.aspnet_User.UserName,
Username2 = i.UserInvited.aspnet_User.UserName,
UsernameInviter = i.UserInviter.aspnet_User.UserName,
RequestText = i.RequestText,
NoteInviter = i.NoteInviter,
ResendInvitationCount = (i.ResendInvitationCount.HasValue) ? i.ResendInvitationCount.Value : 0,
NoteInvited = i.NoteInvited,
MeetingType = i.MeetingType.TypeName
};
...
result =
(from i in _dbContext.Meetings
where i.UserInviterID == CurrentUserID
&& i.MeetingStatus == null
&& !i.IsTex
&& DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
select i).Select(projection);
This keeps the entire part of the query server-side, exactly as if you had written it out in each query.

Yes, you can create a method that returns a ITW2012Mobile.Core.DataTable.MeetingModel2Tmp for you and call that method in the select.
Something like
private ITW2012Mobile.Core.DataTable.MeetingModel2Tmp MethodName(TypeOfI i)
{
return new ITW2012Mobile.Core.DataTable.MeetingModel2Tmp() {
//same stuff as in your question's initializer
};
}
and call it with
result = from i in _dbContext.Meetings
where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && //!i.IsTex &&
DbFunctions.AddMinutes(DbFunctions.AddHours(i.MeetingTime.Day, i.MeetingTime.Hour).Value, i.MeetingTime.Minute).Value > dateWithTime
//where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && DbFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
select MethodName(i);
The query will get compiled down into LINQ extension methods anyway, and .Select() takes in a Func<TSource, TResult> as an argument. A Func is just a delegate (method) that has one input parameter (of type TSource) and returns a TResult object.

Related

The cast to value type System.Boolean failed because the materialized value is null, result type's generic parameter must use a nullable type

This code was working before but now I've got this error: The cast to value type 'System.Boolean' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
public async Task<ActionResult> BankDepositVoucher(BankDepositVoucherSearchViewModel search, int? PageNo)
{
var model = new BankDepositVoucherListViewModel
{
Search = search ?? new BankDepositVoucherSearchViewModel()
};
if (search != null)
{
search.StartDate = search.StartDate.ToStartOfDay();
search.EndDate = search.EndDate.ToEndOfDay();
}
try
{
var Vouchers = DbManager.Invoices.Include(x => x.BankDepositVoucher)
.Where(x => x.Type == InvoiceType.BankDepositVoucher
&& (x.VoucherNumber == search.VoucherNo || search.VoucherNo == null)
&& (x.BankDepositVoucher.SlipNo.Contains(search.SlipNo) || search.SlipNo == null)
&& (x.BankDepositVoucher.ChequeNo.Contains(search.ChequeNo) || search.ChequeNo == null)
&& (x.BankDepositVoucher.Bank.AccountName.Contains(search.BankDetails)
|| search.BankDetails == null)
&& (x.BankDepositVoucher.AccountName.Contains(search.AccountName) || search.AccountName == null)
&& (x.BankDepositVoucher.Narration.Contains(search.Narration) || search.Narration == null)
&& (x.TotalAmount == search.Amount || search.Amount == null)
&& (x.Date >= search.StartDate || search.StartDate == null)
&& (x.Date <= search.EndDate || search.EndDate == null));
//model.Pager = new Pager(await Vouchers.CountAsync(), PageNo, 10);
model.Vouchers = await Vouchers.OrderByDescending(x => x.VoucherNumber)
//.Skip((model.Pager.CurrentPage - 1) * model.Pager.PageSize)
//.Take(model.Pager.PageSize)
.Select(x => new BankDepositVoucherBaseViewModel
{
Id = x.Id,
VoucherNumber = x.VoucherNumber,
AccountName = x.BankDepositVoucher.AccountName,
BankAccountName = x.BankDepositVoucher.Bank.AccountName,
Date = x.Date,
ChequeNo = x.BankDepositVoucher.ChequeNo,
Narration = x.BankDepositVoucher.Narration,
SlipNo = x.BankDepositVoucher.SlipNo,
TotalAmount = x.TotalAmount,
IsCleared = x.BankDepositVoucher.IsCleared
}).ToListAsync();
}
catch (Exception ex)
{
Console.WriteLine("", ex.Message);
}
return PartialView(model);
}
This is the part throwing above mentioned exception
model.Vouchers = await Vouchers.OrderByDescending(x => x.VoucherNumber)
//.Skip((model.Pager.CurrentPage - 1) * model.Pager.PageSize)
//.Take(model.Pager.PageSize)
.Select(x => new BankDepositVoucherBaseViewModel
{
Id = x.Id,
VoucherNumber = x.VoucherNumber,
AccountName = x.BankDepositVoucher.AccountName,
BankAccountName = x.BankDepositVoucher.Bank.AccountName,
Date = x.Date,
ChequeNo = x.BankDepositVoucher.ChequeNo,
Narration = x.BankDepositVoucher.Narration,
SlipNo = x.BankDepositVoucher.SlipNo,
TotalAmount = x.TotalAmount,
IsCleared = x.BankDepositVoucher.IsCleared
}).ToListAsync();
The issue is likely that when populating the view model it cannot deal with the fact that a record may not have a BankDepositVoucher.
For instance:
IsCleared = x.BankDepositVoucher.IsCleared
This should probably be:
IsCleared = x.BankDepositVoucher?.IsCleared ?? false
One other thing to improve performance considerably:
While it may look concise in the code to write statements like this:
.Where(x => x.Type == InvoiceType.BankDepositVoucher
&& (x.VoucherNumber == search.VoucherNo || search.VoucherNo == null)
&& (x.BankDepositVoucher.SlipNo.Contains(search.SlipNo) || search.SlipNo == null)
&& (x.BankDepositVoucher.ChequeNo.Contains(search.ChequeNo) || search.ChequeNo == null)
&& (x.BankDepositVoucher.Bank.AccountName.Contains(search.BankDetails)
|| search.BankDetails == null)
&& (x.BankDepositVoucher.AccountName.Contains(search.AccountName) || search.AccountName == null)
&& (x.BankDepositVoucher.Narration.Contains(search.Narration) || search.Narration == null)
&& (x.TotalAmount == search.Amount || search.Amount == null)
&& (x.Date >= search.StartDate || search.StartDate == null)
&& (x.Date <= search.EndDate || search.EndDate == null));
It is more efficient to write it out as:
.Where(x => x.Type == InvoiceType.BankDepositVoucher);
if(!string.IsNullOrEmpty(search.VoucherNo))
Voucher = Voucher.Where(x => x.VoucherNumber == search.VoucherNo);
if(!string.IsNullOrEmpty(search.SlipNo))
Voucher = Voucher.Where(x => x.BankDepositVoucher.SlipNo.Contains(search.SlipNo))
// etc.
The reason is that in the first case you are generating a much larger SQL statement to be sent to the database, and it is quite easy to "slip up" on conditions if that query is ever edited in the future. (missing parenthesis, etc.) The second example only adds conditions to the query if they are needed, keeping the resulting SQL statement much more compact.

How to refactor this linq query?

I have this below linq query of which 95% remains the same across 6 different scenarios.How can I refactor it so that I can write in one function and use it for all the cases?
var results = await (from r in Requests
join ra in RequestAuthorisers
on cr.ID equals ra._REQUEST_ID
where cr.FACILITY_ID == facilityId
&& (r._REQUEST_STATUS_ID == RequestSubmitted || r._REQUEST_STATUS_ID == RequestPartiallyAuthorised )//check against more status codes based on different conditions
&& ra.FACILITY_USER_ID == facilityUserId//don't check this if admin
&& ra.AUTHORIZATION_DATE != null
&& ra.REJECTION_DATE == null
select new
{
FacilityId = r.FACILITY_ID,
VersionId = r.VERSION_ID,
CreatedByTitle = r.CREATED_BY_USER_TITLE,
CreatedByFirstName = r.CREATED_BY_USER_FIRST_NAME,
CreatedByLastName = r.CREATED_BY_USER_LAST_NAME,
RequestDate = r.SUBMITTED_DATE,
RequestId = r.ID,
RequestType = r._TYPE_ID,
Status = r._REQUEST_STATUS_ID
}).ToListAsync();
var RequestResponse = results.Select(
r => new RequestResponseDto
{
FacilityId = r.FacilityId,
VersionId = r.VersionId,
CreatedByTitle = r.CreatedByTitle,
CreatedByFirstName = r.CreatedByFirstName,
CreatedByLastName = r.CreatedByLastName,
RequestDate = Convert.ToDateTime(r.RequestDate).ToString("s"),
RequestType = ((RequestType)r.RequestType).ToString(),
Status = ((RequestStatus)r.Status).ToString()
}).ToList();
As you can the scenarios/queries differ only by if isAdmin and check against more status codes(as commented above), rest of the part becomes same.
I am using LINQ to EF(DB First).
Thanks in advance.
Why not pass a boolean into the method:
public RequestResponseDto MyMethod(bool isAdmin, Status status)
{
...
&&
((status == Status.Status1 && (r._REQUEST_STATUS_ID == RequestSubmitted || r._REQUEST_STATUS_ID == RequestPartiallyAuthorised))
||
(status == Status.Status2 && (r._REQUEST_STATUS_ID == Something))
||
(status == Status.Status3 && (r._REQUEST_STATUS_ID == SomethingElse || r._REQUEST_STATUS_ID == AnotherThing)))
...
&& (isAdmin || ra.FACILITY_USER_ID == facilityUserId)
...
}

Include where clause on linq query when param is not null Npgsql

I have following method that registers a contact in database, but before register I check the contact exists or not:
bool RegisterContact(Contact contactInfo) {
bool entityExists =
_dbContext.Contacts.FirstOrDefault(
p => (p.FilesID.Equals(contactInfo.FilesID))
&& (p.EmailAddress ==
(string.IsNullOrEmpty(
contactInfo.EmailAddress)
? p.EmailAddress
: contactInfo.EmailAddress))
&&
(p.DisplayName ==
(string.IsNullOrEmpty(
contactInfo.DisplayName)
? p.DisplayName
: contactInfo.DisplayName)));
}
this query includes the fields that contain value (not null) in search condition (FilesID, EmailAddress, DisplayName)
this technique works fine in MSSQL, today i changed the database manager to PostgreSQL and use Npgsql.
All things work except above linq query, which raises an exception with message of : "could not determine data type of parameter $2"
I was forced to solve it in this way:
bool RegisterContact(Contact contactInfo)
{
Contact entityExists = null;
if (string.IsNullOrEmpty(contactInfo.EmailAddress) &&
(string.IsNullOrEmpty(contactInfo.DisplayName)))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p => p.FilesID.Equals(contactInfo.FilesID));
if (!string.IsNullOrEmpty(contactInfo.EmailAddress) && string.IsNullOrEmpty(contactInfo.DisplayName))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p =>
p.FilesID.Equals(contactInfo.FilesID) &&
p.EmailAddress == contactInfo.EmailAddress);
if (string.IsNullOrEmpty(contactInfo.EmailAddress) && !string.IsNullOrEmpty(contactInfo.DisplayName))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p =>
p.FilesID.Equals(contactInfo.FilesID) &&
p.DisplayName == contactInfo.DisplayName);
if (!string.IsNullOrEmpty(contactInfo.EmailAddress) &&
!string.IsNullOrEmpty(contactInfo.DisplayName))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p =>
p.FilesID.Equals(contactInfo.FilesID) &&
p.EmailAddress == contactInfo.EmailAddress &&
p.DisplayName == contactInfo.DisplayName);
}
Is this Npgsql bug or by design? any known solutions/workarounds for the problem?
I currently have the same cases. I think the problem is the lack of recognition, by NpgSQL, of string.IsNullOrEmpty.
I replaced the test with a check on empty string, always recognizing as not NULL the input parameter.
-- bad
var data = from art in _ctx.Set<Soleo.Model.DLAR>()
from iva in _ctx.Set<Soleo.Model.DLAI>().Where(k => k.DITTA == art.DITTA && k.COD == art.CIVA).DefaultIfEmpty()
from fam in _ctx.Set<Soleo.Model.DLFA>().Where(k => k.DITTA == art.DITTA && k.COD == art.FAM).DefaultIfEmpty()
from mar in _ctx.Set<Soleo.Model.DLMA>().Where(k => k.DITTA == art.DITTA && k.COD == art.MAR).DefaultIfEmpty()
from udm in _ctx.Set<Soleo.Model.DLUM>().Where(k => k.DITTA == art.DITTA && k.COD == art.UM).DefaultIfEmpty()
where art.DITTA == DLAUTH.Config.Current.DITTA && art.COD.Contains(sel_cod) && art.DES.Contains(sel_des)
&& (string.IsNullOrEmpty(sel_fam) || string.Compare(art.FAM, sel_fam, true) == 0)
&& (string.IsNullOrEmpty(sel_mar) || string.Compare(art.MAR, sel_mar, true) == 0)
&& (art.DIS >= sel_dis_da && art.DIS <= sel_dis_a)
select new
{
COD = art.COD,
DES = art.DES,
DES_UDM = udm.DES,
DES_MAR = mar.DES,
DES_FAM = fam.DES,
DES_CIVA = iva.DES,
MAG1 = art.MAG1,
MAG2 = art.MAG2,
DES_DIS = art.DIS == 1 ? "Si" : "No"
};
-- good:
var data = from art in _ctx.Set<Soleo.Model.DLAR>()
from iva in _ctx.Set<Soleo.Model.DLAI>().Where(k => k.DITTA == art.DITTA && k.COD == art.CIVA).DefaultIfEmpty()
from fam in _ctx.Set<Soleo.Model.DLFA>().Where(k => k.DITTA == art.DITTA && k.COD == art.FAM).DefaultIfEmpty()
from mar in _ctx.Set<Soleo.Model.DLMA>().Where(k => k.DITTA == art.DITTA && k.COD == art.MAR).DefaultIfEmpty()
from udm in _ctx.Set<Soleo.Model.DLUM>().Where(k => k.DITTA == art.DITTA && k.COD == art.UM).DefaultIfEmpty()
where art.DITTA == DLAUTH.Config.Current.DITTA && art.COD.Contains(sel_cod) && art.DES.Contains(sel_des)
&& (string.Compare(sel_fam, "", true) == 0 || string.Compare(art.FAM, sel_fam, true) == 0)
&& (string.Compare(sel_mar, "", true) == 0 || string.Compare(art.MAR, sel_mar, true) == 0)
&& (art.DIS >= sel_dis_da && art.DIS <= sel_dis_a)
select new
{
COD = art.COD,
DES = art.DES,
DES_UDM = udm.DES,
DES_MAR = mar.DES,
DES_FAM = fam.DES,
DES_CIVA = iva.DES,
MAG1 = art.MAG1,
MAG2 = art.MAG2,
DES_DIS = art.DIS == 1 ? "Si" : "No"
};
But I do not think this is the solution. I will report the case to NpgSQL.

How to implement search functionality in C#/ASP.NET MVC

I am developing an ASP.NET MVC 3 application using C# and Razor.
I have a search form that looks like this:
The search form works in the following way:
The user selects which property they want to search on.
The user selects how they want to match the search string (e.g. contains, starts with, ends with, equals, etc).
The user enters a search term and clicks Search.
The selections in the first drop down related directly to a property in my ADO.NET Entity Framework model class (and therefore directly to a table column).
Users need the ability to explicitly select which property and which matching method when searching, e.g. a user will explicitly search for all matches of process number that equals '132'.
My first approach was to use dynamic linq to construct a Where clause from the search criteria (see my original question). However I'm starting to think that this isn't the best way to do it.
I'm also hoping for a solution that doesn't require me to hard code the result for each property + matching criteria combination.
Any suggestions on how I should implement this search? It doesn't have to be using my current search form, totally open to any other ideas that fit the requirements.
Have you looked into using Lucene.NET for this project? given the nature of your searches it would be very simple to build that using Lucene, as it allows you to combine filters on different columns just like your requirements
You can build expression tree for where predicate using code. For example,
public static IQueryable<T> DynamicWhere<T>(this IQueryable<T> src, string propertyName, string value)
{
var pe = Expression.Parameter(typeof(T), "t");
var left = Expression.Property(pe, typeof(T).GetProperty(propertyName));
var right = Expression.Constant(value);
// Illustrated a equality condition but you can put a switch based on some parameter
// to have different operators
var condition = Expression.Equal(left, right);
var predicate = Expression.Lambda<Func<T, bool>>(condition, pe);
return src.Where(predicate);
}
Use it as Orders.DynamicWhere(searchBy, searchValue). You can add one more parameter to accept the operator such as Equals, Greater Than etc to complete the function.
See these links for more info:
http://msdn.microsoft.com/en-us/library/bb882637.aspx
http://msdn.microsoft.com/en-us/library/bb397951.aspx
Also check list of methods on the Expression class to get an idea.
You can use Dynamic Linq and you can create the Where clausole with a utility class like this:
public class Criteria
{
StringBuilder sb = new StringBuilder();
bool first = true;
public void And(string property, string dbOperator, string value) {
if (first)
{
sb.Append(" ").Append(property).Append(" ");
sb.Append(" ").Append(dbOperator).Append(" ");
sb.Append(" ").Append(value).Append(" ");
first = false;
}
else
{
sb.Append(" && ").Append(property).Append(" ");
sb.Append(" ").Append(dbOperator).Append(" ");
sb.Append(" ").Append(value).Append(" ");
}
}
public void Or(string property, string dbOperator, string value)
{
if (first)
{
sb.Append(" ").Append(property).Append(" ");
sb.Append(" ").Append(dbOperator).Append(" ");
sb.Append(" ").Append(value).Append(" ");
first = false;
}
else
{
sb.Append(" || ").Append(property).Append(" ");
sb.Append(" ").Append(dbOperator).Append(" ");
sb.Append(" ").Append(value).Append(" ");
}
}
public string ToString()
{
return sb.ToString();
}
}
So you can build a Criteria with many properties using Or or And methods and put it in the Where operator of Dynamic Linq.
We started out resolving similar queries against our Entity Framework model using dynamic linq queries. However, our attempts to generalize query generation resulted in bad performance due to EF being confused by the resulting complex expressions, so in the end horrible SQL was produced.
We resorted to Entity SQL.
Not sure if you are using MS SQL. Seems SQL could do most of the work for you, and you can build dynamic queries. Obviously the select/from statement needs work, but you can get the idea from the where clause.
DECLARE #SEARCHTYPE VARCHAR(20)
DECLARE #SEARCHTERM VARCHAR(100)
SELECT
[FIELDS]
FROM
[TABLE]
WHERE
(#SEARCHTYPE = 'BEGINSWITH' AND [FIELD] LIKE #SEARCHTERM + '%') OR
(#SEARCHTYPE = 'ENDSWITH' AND [FIELD] LIKE '%' + #SEARCHTERM) OR
(#SEARCHTYPE = 'EQUALS' AND [FIELD] = #SEARCHTERM)
You could have the first combo data source set to myEntityObject.GetType().GetProperties(), the second to a list of displayable Funcs<string, string, bool>, like this:
public class ComboPredicate
{
public Func<string, string, bool> Func {get; set;}
public string Name {get; set; }
}
Later, when you load the form:
comboProperty.Datasource = myEntityObject.GetType().GetProperties()
comboOperation.Datasource = new List<Predicate>
{
{
Name = "Contains",
Predicate = (s1, s2) => s1 != null && s1.Contains(s2),
},
{
Name = "Equals",
Predicate = (s1, s2) => string.Compare(s1, s2) == 0,
},
//...
}
And later, when you want to select your entities:
var propertyInfo = (PropertyInfo)comboProperty.SelectedValue;
var predicate = ((ComboPredicate)comboOperation.SelectedValue).Predicate;
var filteredObjects = objects.Where(o => predicate(propertyInfo.GetValue(o, null).ToString(), textBoxValue.Text));
create method and call it on button click demo below
public List gettaskssdata(int c, int userid, string a, string StartDate, string EndDate, string ProjectID, string statusid)
{
List<tbltask> tbtask = new List<tbltask>();
var selectproject = entity.tbluserprojects.Where(x => x.user_id == userid).Select(x => x.Projectid);
if (statusid != "" && ProjectID != "" && a != "" && StartDate != "" && EndDate != "")
{
int pid = Convert.ToInt32(ProjectID);
int sid = Convert.ToInt32(statusid);
DateTime sdate = Convert.ToDateTime(StartDate).Date;
DateTime edate = Convert.ToDateTime(EndDate).Date;
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblproject.ProjectId == pid) && (x.tblstatu.StatusId == sid) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a)) && (x.StartDate >= sdate && x.EndDate <= edate)).OrderByDescending(x => x.ProjectId).ToList();
}
else if (statusid == "" && ProjectID != "" && a != "" && StartDate != "" && EndDate != "")
{
int pid = Convert.ToInt32(ProjectID);
DateTime sdate = Convert.ToDateTime(StartDate).Date;
DateTime edate = Convert.ToDateTime(EndDate).Date;
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblproject.ProjectId == pid) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a)) && (x.StartDate >= sdate && x.EndDate <= edate)).OrderByDescending(x => x.ProjectId).ToList();
}
else if (ProjectID == "" && statusid != "" && a != "" && StartDate != "" && EndDate != "")
{
int sid = Convert.ToInt32(statusid);
DateTime sdate = Convert.ToDateTime(StartDate).Date;
DateTime edate = Convert.ToDateTime(EndDate).Date;
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblstatu.StatusId == sid) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a)) && (x.StartDate >= sdate && x.EndDate <= edate)).OrderByDescending(x => x.ProjectId).ToList();
}
else if(ProjectID!="" && StartDate == "" && EndDate == "" && statusid == "" && a == "")
{
int pid = Convert.ToInt32(ProjectID);
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblproject.ProjectId == pid)).OrderByDescending(x => x.ProjectId).ToList();
}
else if(statusid!="" && ProjectID=="" && StartDate == "" && EndDate == "" && a == "")
{
int sid = Convert.ToInt32(statusid);
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblstatu.StatusId == sid) ).OrderByDescending(x => x.ProjectId).ToList();
}
else if (a == "" && StartDate != "" && EndDate != "" && ProjectID != "")
{
int pid = Convert.ToInt32(ProjectID);
DateTime sdate = Convert.ToDateTime(StartDate).Date;
DateTime edate = Convert.ToDateTime(EndDate).Date;
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.ProjectId == pid) && (x.StartDate >= sdate && x.EndDate <= edate)).OrderByDescending(x => x.ProjectId).ToList();
}
else if (StartDate == "" && EndDate == "" && statusid != "" && ProjectID != "" && a != "")
{
int pid = Convert.ToInt32(ProjectID);
int sid = Convert.ToInt32(statusid);
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblproject.ProjectId == pid) && (x.tblstatu.StatusId == sid) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a))).OrderByDescending(x => x.ProjectId).ToList();
}
else if (a == "" && StartDate == "" && EndDate == "" && ProjectID != "" && statusid != "")
{
int pid = Convert.ToInt32(ProjectID);
int sid = Convert.ToInt32(statusid);
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Include(x => x.tblstatu).Where(x => selectproject.Contains(x.ProjectId) && x.tblproject.company_id == c && x.tblproject.ProjectId == pid && x.tblstatu.StatusId == sid).OrderByDescending(x => x.ProjectId).ToList();
}
else if (a != "" && StartDate == "" && EndDate == "" && ProjectID == "" && statusid == "")
{
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a))).OrderByDescending(x => x.ProjectId).ToList();
}
else if (a != "" && ProjectID != "" && StartDate == "" && EndDate == "" && statusid == "")
{
int pid = Convert.ToInt32(ProjectID);
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.tblproject.ProjectId == pid) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a))).OrderByDescending(x => x.ProjectId).ToList();
}
else if (a != "" && StartDate != "" && EndDate != "" && ProjectID == "" && statusid == "")
{
DateTime sdate = Convert.ToDateTime(StartDate).Date;
DateTime edate = Convert.ToDateTime(EndDate).Date;
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && (x.tblproject.company_id == c) && (x.TaskName.Contains(a) || x.tbUser.User_name.Contains(a)) && (x.StartDate >= sdate && x.EndDate <= edate)).OrderByDescending(x => x.ProjectId).ToList();
}
else
{
tbtask = entity.tbltasks.Include(x => x.tblproject).Include(x => x.tbUser).Where(x => selectproject.Contains(x.ProjectId) && x.tblproject.company_id == c).OrderByDescending(x => x.ProjectId).ToList();
}
return tbtask;
}

How can i use "COALESCE(SUM..." in linq?

i try to use sum and Coalesce . How can i translate to linq?
SELECT #SumQtyOut=COALESCE(SUM(Qty),0) FROM dbo.StockMovement WHERE FromLocationType=#FromLocationType AND
* FromNo=#FromNo AND FromSeq=#FromSeq AND ItemTypeNo=#ItemTypeNo AND ItemID=#ItemID
i do sometihng :
using (StockProcedureDataContext stock = new StockProcedureDataContext())
{
SumQtyOut = from s in stock.StockMovements
where s.FromLocationType == FromLocationType &&
s.FromNo== FromNo &&
s.FromSeq == FromSeq &&
s.ItemTypeNo == ItemTypeNo &&
s.ItemID == ItemID select
}
This snippet should yield the result you are looking for.
using (StockProcedureDataContext stock = new StockProcedureDataContext())
{
var items = from s in stock.StockMovements
where s.FromLocationType == FromLocationType &&
s.FromNo== FromNo &&
s.FromSeq == FromSeq &&
s.ItemTypeNo == ItemTypeNo &&
s.ItemID == ItemID
select s.Qty ?? 0;
SumQtyOut = items.Sum(x => x);
}
select s.Qty ?? 0 returns 0 if s.Qty is null. items.Sum(x => x) summs up the quantities you have selected.

Categories

Resources