получить имена начинаются с цифр или специальных символов в linq to sql - PullRequest
1 голос
/ 18 октября 2010

Мне нужно получить список имен, который начинается со специальных символов или цифр в запросе linq to sql для моего приложения asp.net mvc (C #).

Я пробовал вот так (что может и небыть эффективным):

public List<User> GetUsersStartingWithNonCharacter()
{
   List<User> _dbUsers = this.GetAllUsers();
   return _dbUsers.Where(p => ((p.FirstName != null && p.FirstName != string.Empty && !char.IsLetter(p.FirstName.ToLower()[0])) || (p.FirstName == null || p.FirstName == string.Empty))).ToList();
}

public List<Users> GetAllUsers()
{
    return (from u in _context.pu_Users
            where !u.Is_Deleted
            select new User
            {
                UserId = u.User_Id,
                Email = u.Email_Address,
                FirstName = u.First_Name,
                LastName = u.Last_Name
            }).ToList();
}

Кто-нибудь может предложить наиболее эффективный способ сделать это в linq to sql?

Ответы [ 3 ]

1 голос
/ 18 октября 2010

Как вы узнаете, что это еще не эффективно?Используйте какой-нибудь инструмент профилировщика, такой как SQL Server Profiler, если вы используете MSSQL, чтобы вы могли отслеживать ваш вызов по базе данных и видеть фактический SQL.Конечно, вы можете только отладить код, чтобы увидеть сгенерированный SQL, но это проще с помощью инструмента профилирования, и вы увидите, сколько времени занимает запрос.

РЕДАКТИРОВАТЬ: Я вижу одну частькак вы можете сделать его более эффективным:

public List<User> GetUsersStartingWithNonCharacter()
{
   List<User> _dbUsers = this.GetAllUsers();
   return _dbUsers.Where(p => ((p.FirstName != null && p.FirstName != string.Empty && !char.IsLetter(p.FirstName.ToLower()[0])) || (p.FirstName == null || p.FirstName == string.Empty))).ToList();
}

public IQueryable<Users> GetAllUsers()
{
    return from u in _context.pu_Users
            where !u.Is_Deleted
            select new User
            {
                UserId = u.User_Id,
                Email = u.Email_Address,
                FirstName = u.First_Name,
                LastName = u.Last_Name
            };
}

Изменение значения GetAllUsers на IQueryable приведет к задержке выполнения запроса до тех пор, пока вы не примените свои фильтры.Это может повлиять на некоторые другие аспекты вашего проекта, но вы должны учитывать это, так как это изменение может привести к выполнению предложения where в базе данных, а не в коде, что приведет к уменьшению трафика данных между вашим приложением и базой данных.Опять же, используйте профилировщик, чтобы увидеть разницу:).

0 голосов
/ 18 октября 2010

Я подозреваю, что все строки будут получены и отфильтрованы в вашем приложении из-за условия:

char.IsLetter(p.FirstName.ToLower()[0])

(Использование регулярного выражения, подобного предложенному в другом ответе, также вытянет все строки и отфильтрует ихклиент.)

Можно проверять символы в строке с помощью функции PATINDEX , но, похоже, она доступна только для LINQ через платформу Entity.

Вы можете написать хранимую процедуру, используя PATINDEX напрямую, чтобы проверить первый символ для оптимизации вашего запроса.Примеры запросов можно найти по адресу http://www.databasejournal.com/features/mssql/article.php/3071531/Using-SQL-Servers-CHARINDEX-and-PATINDEX.htm.

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

0 голосов
/ 18 октября 2010

Я буду использовать Regular Expression в этом сценарии

Вот мой пример кода

 return _dbUsers.Where(p=>p.FirstName!=String.Empty)
                . Where(p => Regex.Match(p.Firstname[0].ToString(), "[a-zA-Z]").Success).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...