s23user Ответов: 1

Как я могу решить эти проблемы (linq to SQL)


Я новичок в программировании. Я пытаюсь добиться того, чтобы получить следующие вопросы (которые выделены жирным шрифтом). Какие изменения мне нужно внести в свои коды для их достижения?

My code:
public static int CountEmployeesByName(string[] namesToSearch)
{
using (ApplicationEntities context = new ApplicationEntities())
{
var queries = new List<IEnumerable<employee>>();
string nameParam;
foreach (string name in namesToSearch)
{
nameParam = name;
//search for employees by name
queries.Add((from e in context.employees
where e.name == nameParam
select e));
}
return queries.Sum(q => q.Count());
}
}
 
public static void UnitTests()
{ //Populate with test data
using (ApplicationEntities context = new ApplicationEntities())
{
context.Database.ExecuteSqlCommand(@" TRUNCATE TABLE employees
INSERT INTO employees (name) VALUES ('Niño');
INSERT INTO employees (name) VALUES (N'?????');
SET ANSI_WARNINGS OFF;
INSERT INTO employees (name) VALUES ('VeryLongName');
INSERT INTO employees (name) VALUES ('Name1');
INSERT INTO employees (name) VALUES ('Name2');
INSERT INTO employees (name) VALUES ('Nick');");
}
 
//Question 
//The function is always failing to find any but the last name in the namesToSearch array.
Debug.Assert(CountEmployeesByName(new string[] { "Name1", "Name2", "NoName3" }) == 2);
//It fails . it finds 0 why? Shouldnt it return 2? What do i make change in my code?
//Question 
//Every matching employee record is being retrieved from the database server (very inefficient).
//The SQL engine should do the counting.
Debug.Assert(CountEmployeesByName(new string[] { "Nick", "Name1" }) == 3);
//Fails.. it counts only 2, Why?
 
/* //Question 
//What changes sdo i make in The function so that it should not be running a query for each //search name. It should run exactly 1 SQL statement each time the function is called.
Debug.Assert(CountEmployeesByName(new string[] { "Nick", "Name1" }) == 3); 
 
//Question 
//One employee can be counted twice. It should return number of unique employees.
Debug.Assert(CountEmployeesByName(new string[] { "Name1", "name1" }) == 1);
//it finds 2, what changes do i make ?
}
static void Main(string[] args)
{
UnitTests();
}

1 Ответов

Рейтинг:
1

Maciej Los

Вопрос№1
Функция всегда не может найти ничего, кроме фамилии в массиве namesToSearch.
Debug.Assert(CountEmployeesByName(new string[] { "Name1", "Name2", "NoName3" }) == 2);

Он терпит неудачу . он находит 0 почему? Разве он не должен вернуть 2? Что я должен изменить в своем коде?


Что ж... вам даже не нужно создавать локальные List<IEnumerable<employee>> чтобы иметь возможность получить количество сотрудников, имя которых совпадает с именем строки в массиве. Тело функции можно упростить таким образом:
return context.employees.Where(x=>namesToSearch.Any(y=>y==x)).Count();


Надеюсь, это решит и другие ваши проблемы.



[РЕДАКТИРОВАТЬ]
Если вы хотите предоставить пользовательское сравнение, вам необходимо реализовать метод Equals[^]. Тогда вы сможете сравнить имя eployee независимо от верхнего / нижнего регистра.

В этот момент Вы можете реализовать метод Equals, используя Строка.Метод Equals() [^].
Например:
//parameters are:
//namesToFind {"nick", "Name1","Name2","NoName3"};
//nick
return context.employee.Where(x=>namesToFind.Any(y=>String.Equals(y, x,StringComparison.OrdinalIgnoreCase))).Count();


Выше код должен вернуться 3.
[/РЕДАКТИРОВАТЬ]



[Правка#2]
Чтобы вернуть различные значения, используйте Метод Distinct() [^]:
return context.employee.Where(...).Distinct().Count();


[/EDIT#2]


s23user

Большое вам спасибо за решение. Какие изменения я должен внести в последний вопрос?

Maciej Los

Пожалуйста, прочтите мой обновленный ответ...
Вы должны использовать Distinct() метод как раз перед этим Count().