Amr Mohammad Rashad Ответов: 0

LINQ to object оценка короткого замыкания не работает


Приветствия,

Мне было интересно, работает ли оценка короткого замыкания для логических операторов с LINQ to Objects или нет, поскольку у меня есть приведенный ниже код, и оценка короткого замыкания не работает для него.

// this code is within UI namespace

List<Employee> wList = BLL.GetEmployeeAlternatives(id);
List<int?> oList = BLL.GetEmployeesManagedById(id);

dgvEmpList.DataSource = BLL.GetCustomers().Where(c => BLL.Misc.Instantiation.LoginUser.IsAdmin ||
(c.AccountManagerID == BLL.Misc.Instantiation.LoginUser.EmployeeID ||
 wList.Any(r => r.AbsentID == c.AccountManagerID) ||
  oList.Any(m => m.HasValue && m.Value == c.AccountManagerID)));


Методы уровня бизнес-логики, GetEmployeeAlternatives и GetEmployeesManagedById, вызывающие методы веб-служб, GetEmployeeAlternativesService и GetEmployeesManagedById соответственно, которые, в свою очередь, вызывают методы в пределах уровня доступа к данным и методы уровня доступа к данным, имеющие дело с моделью Entity Framework. Цепочка вызовов выглядит следующим образом.

// Business Logic Layer method

public static List<Employee> GetEmployeeAlternatives(int id)
{
    try
    {
        return myservice.GetEmployeeAlternatives(id);
    }
    catch (Exception e)
    {
#if DEBUG
    System.Diagnostics.Trace.WriteLine(e.Message);
#endif
    throw new Exception("Oops! Something went wrong.");
    }
}


// Service Method
public List<int?> GetEmployeeAlternatives(int id)
{
    try
    {
        Authentication oAuth = new Authentication();
        return oAuth.GetEmployeeAlternatives(id);
    }
    catch (Exception e)
    {
#if DEBUG
    System.Diagnostics.Trace.WriteLine(e.Message);
#endif
        throw new Exception("Oops! Something went wrong.");
    }
}


// Data Access Layer method

public List<Employee> GetEmployeeAlternatives(int id)
{
    try
    {
        return MyModel
                .Employee
                    .Where(a => a.ReplacedID == id &&
(DbFunctions.TruncateTime(DateTime.Now) >= DbFunctions.TruncateTime(a.ReplaceDate) && 
DbFunctions.TruncateTime(DateTime.Now) <= DbFunctions.TruncateTime(DbFunctions.AddDays(a.ReplaceDate, a.NumDays))
)).ToList();
    }
    catch (Exception e)
    {
#if DEBUG
    System.Diagnostics.Trace.WriteLine(e.Message);
#endif  
        throw new Exception("Oops! Something went wrong.");
    }
}


Кстати, я на 100% уверен, что SQL Server поддерживает оценку короткого замыкания, однако он не гарантирует ассоциацию оценки выражения (т. е. левую или правую). Это означает, что если у меня есть что-то подобное

WHERE X <> 1 AND Y <> 2


Это не будет, и я не могу быть уверен, что он будет оцениваться слева направо или наоборот, это зависит от движка, чтобы решить, какое выражение оценивать первым в соответствии с метриками оптимизации оценки движка.

Что я уже пробовал:

Я попытался поискать его в google, однако все, что я видел, - это темы LINQ to SQL

Amr Mohammad Rashad

Никто раньше не сталкивался с такой проблемой?!!!

Richard Deeming

Оценка короткого замыкания должна работать нормально. Почему ты думаешь, что это не так?

Если это так, то GetEmployeeAlternatives и GetEmployeesManagedById методы всегда вызываются, это потому, что вы их вызываете до произошло какое-то короткое замыкание.

Amr Mohammad Rashad

Ленивая загрузка? Основываясь на моих знаниях, что когда вы пишете такое выражение, как "List<employee> wList = BLL.GetEmployeeAlternatives(ИД);" метод "БЛЛ.GetEmployeeAlternatives(код)" не назовут, пока я пытался получить доступ к переменной wList и использовать его вот почему я говорю, что оценка короткого замыкания не получилось, как я ожидал, потому что в метод where условие я сначала обращались "wList" потом "oList", что означает первый способ БЛЛ.Getemployeeealternatives (id); так что если первые два условия где FALSE (т. е. где(c => BLL.Misc.Instantiation.LoginUser.IsAdmin ||
(С. AccountManagerID == БЛЛ.Разное.Инстанцирование.LoginUser.EmployeeID), то метод " BLL. Getemployeeealternatives(id);" будет и возвращает данные в соответствии с концепцией загрузки lazey, и если третье условие оценивается как TRUE "wList.Any(r => r.AbsentID == c.AccountManagerID)", то метод "BLL.GetEmployeesManagedById(id);" не будет вызван из-за короткого замыкания. Надеюсь, моя точка зрения ясна

0 Ответов