How to match list values in linq condition?
I have one list of IDs, so these ids have to match in condition and get data from one table sol how?
public ActionResult StudentSelect(
long? CompanyId,
long? CompanyLocationId,
long? ClassId,
long? SectionId,
long? AcademicId,
long? ExamId) //) //long? SectionId)
Below RegId is list of student's registration Ids
{
var RegId = (
from a in db.Student_Marks_Percentage
where a.Delete_Flag == false &&
a.Exam_Id == ExamId &&
a.Academic_Year_Id == AcademicId &&
a.Class_Id == ClassId
select a.Registration_Id)
.ToList();
List<StudentList> Student = new List<StudentList>();
if (AcademicId != null &&
CompanyId != null &&
CompanyLocationId != null &&
ClassId == null &&
SectionId == null) //&& )//&& ClassId != null) //)
{
Student = (
from a in db.Student_Re_Admission
join b in db.Student_Registration on a.Registration_Id equals b.Registration_Id
join c in db.Student_Roll_No_Assign on a.Registration_Id equals c.Registration_Id
where c.Academic_Year_Id == AcademicId &&
c.Company_ID == CompanyId &&
c.COMPANY_LOCATION_ID == CompanyLocationId &&
a.Academic_Year_Id == AcademicId &&
c.Class_Id == ClassId &&
a.Class_Id == ClassId &&
a.Section_Id == SectionId &&
c.Section_Id == SectionId &&
Here I have to compare those all list of ids to a.Registration_Id
a.Registration_Id != RegIds &&
a.Promoted == false &&
a.Delete_Flag == false
//a.Academic_Year_Id == AcademicId &&
//a.Company_ID == CompanyId &&
//a.COMPANY_LOCATION_ID == CompanyLocationId
select new StudentList()
{
Registration_Id = a.Registration_Id,
Admission_No = a.Admission_No,
Student_First_Name = a.Student_First_Name,
Student_Middle_Name = a.Student_Middle_Name,
Student_Last_Name = a.Student_Last_Name,
Set_Roll_No = c.Set_Roll_No,
Roll_Id = c.Roll_Id
})
.OrderBy(a => a.Registration_Id)
.ToList();
ViewBag.StudentList = Student.ToList();
return PartialView();
}
}
I tried like below but getting same data of student list..
var merged = new List<StudentList>(Student);
merged.Except(Student.Where(p2 => RegId.Exists(p1 => p2.Registration_Id != p1.Registration_Id)));
I think you just need to replace a.Registration_Id != RegIds with:
!RegIDs.Contains(a.Registration_Id)
First var list by which have to compare
var RegId = (from a in db.Student_Marks_Percentage
where a.Delete_Flag == false
&& a.Exam_Id == ExamId
&& a.Academic_Year_Id == AcademicId
&& a.Class_Id == ClassId
select a).ToList();
second list of which data have to get
List<StudentList> Student = new List<StudentList>();
if (AcademicId != null && CompanyId != null && CompanyLocationId != null && ClassId == null && SectionId == null) //&& )//&& ClassId != null) //)
{
Student = (from a in db.Student_Re_Admission
join b in db.Student_Registration on a.Registration_Id equals b.Registration_Id
join c in db.Student_Roll_No_Assign on a.Registration_Id equals c.Registration_Id
where c.Academic_Year_Id == AcademicId && c.Company_ID == CompanyId && c.COMPANY_LOCATION_ID == CompanyLocationId
&& a.Academic_Year_Id == AcademicId && c.Class_Id == ClassId && a.Class_Id == ClassId
&& a.Section_Id == SectionId && c.Section_Id == SectionId
//&& a.Registration_Id != RegId.Contains(a.Registration_Id)
&& a.Promoted == false && a.Delete_Flag == false
//a.Academic_Year_Id == AcademicId && a.Company_ID == CompanyId && a.COMPANY_LOCATION_ID == CompanyLocationId
select new StudentList()
{
Registration_Id = a.Registration_Id,
Admission_No = a.Admission_No,
Student_First_Name = a.Student_First_Name,
Student_Middle_Name = a.Student_Middle_Name,
Student_Last_Name = a.Student_Last_Name,
Set_Roll_No = c.Set_Roll_No,
Roll_Id = c.Roll_Id
}).OrderBy(a => a.Registration_Id).ToList();
}
merging two lists by searching following process.
var merged = Student.Where(a1 => !RegId.Any(a2 => a1.Registration_Id == a2.Registration_Id));
Related
I'm having the next issue, I have the next code
var creditos = from c in db.creditos
join s in db.solicitudDelCliente on c.SolicitudDelClienteID equals s.ID
join cl in db.cliente on s.ClienteID equals cl.ID
where c.Eliminado != true && cl.Eliminado != true && c.NegocioID == negocio_id
select new
{
c.ID,
cl.NumeroCliente,
c.Consecutivo,
NegocioID = negocio_id,
cl.NombreCompleto,
c.FechaAlta,
c.CapitalPrestado,
c.Vencido,
c.Quebranto,
c.Juridico,
c.Liquidado,
c.Reestructura,
c.Eliminado,
c.Estatus,
CapitalPagado = db.movimientos.Where(mm=>mm.CreditoID == c.ID && mm.Eliminado != true && mm.DepositoMovimientoID != null && mm.CategoriaMovimientosID == 2).Select(mm=>mm.Monto).DefaultIfEmpty(0).Sum(),
InteresesPagados = db.movimientos.Where(mm => mm.CreditoID == c.ID && mm.Eliminado != true && mm.DepositoMovimientoID != null && mm.CategoriaMovimientosID == 4).Select(mm => mm.Monto).DefaultIfEmpty(0).Sum(),
SaldoInsoluto = db.movimientos.Where(mm => mm.CreditoID == c.ID && mm.CategoriaMovimientosID == 1).Select(mm => mm.Monto).DefaultIfEmpty(0).Sum() -
db.movimientos.Where(mm => mm.CreditoID == c.ID && mm.Eliminado != true && mm.DepositoMovimientoID != null && mm.CategoriaMovimientosID == 2).Select(mm => mm.Monto).DefaultIfEmpty(0).Sum(),
SaldoDeudorTotal = (db.movimientos.Where(mm => mm.CreditoID == c.ID
&& mm.Eliminado != true
&& mm.DepositoMovimientoID == null
&& mm.CategoriaMovimientosID != 2)
.Select(mm => mm.Monto).DefaultIfEmpty(0).Sum()
- db.movimientos.Where(mm => mm.CreditoID == c.ID
&& mm.Eliminado != true
&& mm.DepositoMovimientoID != null
&& mm.CategoriaMovimientosID != 1)
.Select(mm => mm.Monto).DefaultIfEmpty(0).Sum()),
Migrado = c.Migracion
};
In some of the results of the query, the value of "SaldoDeudorTotal" is negative, I want to control the value, that if the value is -0 then return 0 zero.
var creditos = from c in db.creditos
join s in db.solicitudDelCliente on c.SolicitudDelClienteID equals s.ID
join cl in db.cliente on s.ClienteID equals cl.ID
where c.Eliminado != true && cl.Eliminado != true && c.NegocioID == negocio_id
let total = (db.movimientos.Where(mm => mm.CreditoID == c.ID
&& mm.Eliminado != true
&& mm.DepositoMovimientoID == null
&& mm.CategoriaMovimientosID != 2)
.Select(mm => mm.Monto).DefaultIfEmpty(0).Sum()
- db.movimientos.Where(mm => mm.CreditoID == c.ID
&& mm.Eliminado != true
&& mm.DepositoMovimientoID != null
&& mm.CategoriaMovimientosID != 1)
.Select(mm => mm.Monto).DefaultIfEmpty(0).Sum())
select new
{
c.ID,
cl.NumeroCliente,
c.Consecutivo,
NegocioID = negocio_id,
cl.NombreCompleto,
c.FechaAlta,
c.CapitalPrestado,
c.Vencido,
c.Quebranto,
c.Juridico,
c.Liquidado,
c.Reestructura,
c.Eliminado,
c.Estatus,
CapitalPagado = db.movimientos.Where(mm=>mm.CreditoID == c.ID && mm.Eliminado != true && mm.DepositoMovimientoID != null && mm.CategoriaMovimientosID == 2).Select(mm=>mm.Monto).DefaultIfEmpty(0).Sum(),
InteresesPagados = db.movimientos.Where(mm => mm.CreditoID == c.ID && mm.Eliminado != true && mm.DepositoMovimientoID != null && mm.CategoriaMovimientosID == 4).Select(mm => mm.Monto).DefaultIfEmpty(0).Sum(),
SaldoInsoluto = db.movimientos.Where(mm => mm.CreditoID == c.ID && mm.CategoriaMovimientosID == 1).Select(mm => mm.Monto).DefaultIfEmpty(0).Sum() -
db.movimientos.Where(mm => mm.CreditoID == c.ID && mm.Eliminado != true && mm.DepositoMovimientoID != null && mm.CategoriaMovimientosID == 2).Select(mm => mm.Monto).DefaultIfEmpty(0).Sum(),
SaldoDeudorTotal = total < 0 ? 0 : total,
Migrado = c.Migracion
};
you could use an extension
public static class MyExtension
{
public static int ToPositiveInt(this int value)
{
if (value < 0)
return 0;
else
return value
}
}
and call it at the end of your condition of SaldoDeudorTotal
SaldoDoeudorTotal = (db.movimientos.Where(mm => mm.CreditoID == c.ID
&& mm.Eliminado != true
&& mm.DepositoMovimientoID == null
&& mm.CategoriaMovimientosID != 2).ToPositiveInt()
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)
...
}
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.
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.
This is what i got:
int? productID = (ClientProduct != null ? (int?)ClientProduct.ProductID : null);
result = (from po in ((Chase_Media_Pro_Entity_Model)this.NavigationItem.ObjectContext).raPurchaseOrder_List
where po.ClientID == Client.CustomerID
&& ((object.Equals(po.ClientProductID, productID)) || (po.ClientProductID == (productID ?? po.ClientProductID)))
&& (po.Is_Active == (isActive ?? po.Is_Active))
&& (po.IsApproved == (isApproved ?? po.IsApproved))
orderby po.Is_Active descending, po.IsApproved ascending
select po);
Is there a way to improve this line:
&& ((object.Equals(po.ClientProductID, productID)) || (po.ClientProductID == (productID ?? po.ClientProductID)))
This was the only way i could get the right results.
&& (!productID.HasValue || (productID == po.ClientProductID))
How about
&& ((productID.HasValue && po.ClientProductID.HasValue) ? po.ClientProductID.Value = productID.Value : true)