#c# #linq #generics #lambda
#c# #linq #общие #лямбда
Вопрос:
Я хочу, чтобы мой метод проверял, установлен ли флажок с именем «onlyPresence», затем добавьте новое предложение where или новое выражение в where или используйте if в where .. но я получаю сообщение об ошибке, где я использую ** строку
public IEnumerable<EmployeeInfo> GetAllVisibleEmployeesInfo(string sortBy, string name ,int startRowIndex, int maximumRows, string Department, bool onlyPresence )
{
name = Common.Converter.ConvertToFarsiYK(name ?? "").Trim();
var GetNowString = Common.Date.GregorianToPersian(DateTime.Now.Date, Common.Date.DateStringType.Short);
if (Department == null){Department = "";}
using (LinqDataContext context = DataContext)
{
List<EmployeeInfo> result = context.vwDailyWorks
.Where(q => (q.Visible == true))
.Where(q => (q.DepartmentName.Contains(Department)))
.Where(q => (string.IsNullOrEmpty(name) ||
(q.FirstName.Contains(name) ||
q.LastName.Contains(name) ||
q.Position.Contains(name) ||
q.Floor.Contains(name) ||
(q.Ext_Tel ?? -1).ToString().Contains(name) ||
q.Email.Contains(name) ||
q.DepartmentName.Contains(name)))
)
**.Where(w => { if (onlyPresence) { w.Even_Odd == 1} } )**
.GroupBy(t => t.EmployeeID)
.Select(t => new EmployeeInfo
{
FirstName = t.Max(s => s.FirstName),
LastName = t.Max(s => s.LastName),
Position = t.Max(s => s.Position),
DepartmentName = t.Max(s => s.DepartmentName),
Status2= GetPresent_Status(t.Key),
Extension = t.Max(s => s.Ext_Tel),
Info = GetPresenceInfo(t.Key, false),
ID = t.Key,
Email = t.Max(s => s.Email),
StatusInfo = GetStatusInfo(t.Key, false)
}
)
.OrderBy(sortBy)
.Skip(startRowIndex)
.Take(maximumRows)
.ToList();
return resu<
}
}
Комментарии:
1. какую ошибку вы получаете?
2. @HassanMonjezi Это не та же логика
3. @DavidG, я понял, что логика вопроса — это то
if (onlyPresence) { w.Even_Odd == 1}
, что говоритif(onlyPresence==true)
, что тогда проверьтеw.Even_Odd == 1
. но в любом случае, что касается логики, проблема в том, что @Amirhosein Araghi не возвращает результат за пределами своего оператора if .4. @HassanMonjezi Я просто говорю, что ваша логика неверна, она должна заканчиваться
true
.5. @DavidG Вы правы.
Ответ №1:
Вы можете просто сделать это:
.Where(w => !onlyPresence || w.Even_Odd == 1)
Комментарии:
1. спасибо, но я не знаю, почему, когда установлен другой флажок, я ничего не получил
2. Это новый вопрос, у вас есть свой ответ!
Ответ №2:
что-то вроде
using (LinqDataContext context = DataContext)
{
List<EmployeeInfo> result = context.vwDailyWorks
.Where(q => (q.Visible == true))
.Where(q => (q.DepartmentName.Contains(Department)))
.Where(q => (string.IsNullOrEmpty(name) ||
(q.FirstName.Contains(name) ||
q.LastName.Contains(name) ||
q.Position.Contains(name) ||
q.Floor.Contains(name) ||
(q.Ext_Tel ?? -1).ToString().Contains(name) ||
q.Email.Contains(name) ||
q.DepartmentName.Contains(name)))
);
if (onlyPresence)
{
result = result.Where(w => w.Even_Odd == 1 )
}
result = result
.GroupBy(t => t.EmployeeID)
.Select(t => new EmployeeInfo
{
FirstName = t.Max(s => s.FirstName),
LastName = t.Max(s => s.LastName),
Position = t.Max(s => s.Position),
DepartmentName = t.Max(s => s.DepartmentName),
Status2= GetPresent_Status(t.Key),
Extension = t.Max(s => s.Ext_Tel),
Info = GetPresenceInfo(t.Key, false),
ID = t.Key,
Email = t.Max(s => s.Email),
StatusInfo = GetStatusInfo(t.Key, false)
})
.OrderBy(sortBy)
.Skip(startRowIndex)
.Take(maximumRows)
.ToList();
return resu<
}
Ответ №3:
Прежде всего, параметр predicate
в запрашиваемом.Где должно быть an Expression<Func<VwDailyWork,bool>>
. Или на обычном языке: метод, который принимает объект VwDailyWork и возвращает bool
w => { if (onlyPresence) { w.Even_Odd == 1}
не является Func<VwDailyWork,bool>
. Чего бы вы хотели, если !onlyPresence
? Не проверять вообще?
w => !onlyPresence) || (w.Even_Odd == 1)
Это тот же af:
if (onlyPresence)
возвращает w.Even_odd == 1;
else
возвращает true;
Есть возможности для улучшения
Если вы сделаете это, как вы предложили, тогда значение onlyPresence будет вычисляться один раз для каждой вычисленной VwDailyWork . Аналогично, вы несколько раз проверяете пустоту имени. Не лучше ли было бы оценить их только один раз?
IQueryable<VwDailyWorks> query = dbContext.vwDailyWorks
.Where(q => q.Visible amp;amp; q.DepartmentName.Contains(Department);
if (!String.IsNullOrEmpty(name))
{
// add the name checks
query = query.Where(q => q.FirstName.Contains(name) || ...);
}
if (onlyPresence)
{
// add the check for even_odd == 1
query = query.Where(q => q.even_odd == 1);
}
Теперь вы уверены, что имя и onlyPresence проверяются только один раз.
Если вы будете делать это чаще, я бы посоветовал создать для этого метод расширения. Если вы не знакомы с методами расширения, см. раздел Методы расширения, разоблаченные
public static IQueryable<VwDailyWorks> QueryVwDailyWorks(
this LinqDataContext dbContext
string name,
string department,
bool onlyPresence)
{
IQueryable<VwDailyWorks> query = dbContext.vwDailyWorks
.Where(q => q.Visible
amp;amp; q.DepartmentName.Contains(Department);
if (!String.IsNullOrEmpty(name))
{
// add the name checks
query = query.Where(q => q.FirstName.Contains(name) || ...);
}
if (onlyPresence)
{
// add the check for even_odd == 1
query = query.Where(q => q.even_odd == 1);
}
}
return query;
}
Использование:
string name = ...
string department = ...
bool onlyPresence = ...
using (var dbContext = new DataContext())
{
var result = dbContext.QueryVwDailyWorks(name, department, onlyPresence)
// continue with your original query
.GroupBy(t => t.EmployeeId)
.Select(...)
.OrderBy(...)
.Skip(...)
.Take(...)
.ToList();