Kryteria wyszukiwania za pomocą LINQ (ef core)

0

Posiadam relację jedne-do-wielu. Company -> Employees. key podany przez użytkownika jest frazą, która ma się znaleźć w nazwie firmy lub imieniu pracownika lub nazwisku, jest opcjonalny, jeśli nic nie wpisano zwracam pustą listę.
Mam takie zapytanie ale wygląda ono strasznie chociaż działa zgodnie z założeniami.

  1. Jak to lepiej zaimplementować w ef core?
  2. Obecnie użytkownik podaje jedno słowo po którym szukam, jak zrobić szukanie, jeśli danymi wejściowymi będzie tablica stringów?
  3. Jeśli dojdzie mi dodatkowe kryterium opcjonalne np. data zatrudnienia od-do to czy jest "łatwy" sposób, żeby połączyć dwa kryteria?
var result = _context.Companies
	.Where(c => c.Name.Contains(criteria.Keyword) ||
			    c.Employees.Any(e => e.FirstName.Contains(criteria.Keyword) ||
							         e.LastName.Contains(criteria.Keyword)))
	.Select(c => new Company
	{
		Id = c.Id,
		Name = c.Name,
		Employees = c.Employees.Where(e => e.FirstName.Contains(criteria.Keyword) ||
									       e.LastName.Contains(criteria.Keyword))
	});
public class Company
{
	public int Id { get; set; }
	public string Name { get; set; }
	public IEnumerable<Employee> Employess { get; set; }
}

// pracownik nie ma pola nawigacyjnego do firmy
public class Employee
{
	public int Id { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}
0

Z danymi wejściowymi jako tablica stringów o takie coś Tobie chodzi ?

string[] keywords = new string[] { "Adam", "Firma","Nowak" };
 var result = companies.Where(c => keywords.Any(x=> x == c.Name) || c.Employees.Any(x=> keywords.Any(d=>d == x.FirstName || d == x.LastName))) . Select(...)

Nie rozumiem natomiast czemu po selekcie dokonujesz jeszcze raz selekcji. W Twoim przypadku jeżeli szukamy Kowalskiego to Twój kod zwróci nam firmę A z wszystkimi pracownikami o nazwisku Kowalski, ale nie zwróci innych tam pracowników. No chyba, że taki jest cel.

0
mariano901229 napisał(a):

Z danymi wejściowymi jako tablica stringów o takie coś Tobie chodzi ?

string[] keywords = new string[] { "Adam", "Firma","Nowak" };
 var result = companies.Where(c => keywords.Any(x=> x == c.Name) || c.Employees.Any(x=> keywords.Any(d=>d == x.FirstName || d == x.LastName))) . Select(...)

Prawie, teraz jeśli podam na wejściu kowalski, smith to znajdzie mi firmy których nazwa jest identyczna. Keyword ma być frazą, która ma się zawierać w nazwie firmy itd.. Czyli jeśli zrobię coś takiego

var keywords = new[] { "kow", "th" }

to powinno mi wyświetlić firmę: kowalski i smith. Zamieniłem == na Contains(), odwróciłem strony ale za każdym razem dostaję pustą listę.

mariano901229 napisał(a):

Nie rozumiem natomiast czemu po selekcie dokonujesz jeszcze raz selekcji. W Twoim przypadku jeżeli szukamy Kowalskiego to Twój kod zwróci nam firmę A z wszystkimi pracownikami o nazwisku Kowalski, ale nie zwróci innych tam pracowników. No chyba, że taki jest cel.

Mam taką przykładową firmę

Id: 1;
Name: Kowal
Employees: [
	{
		Id: 1
		FirstName: Jan
		LastName: Kowalski
	},
	{
		Id: 2
		FirstName: John
		LastName: Smith
	}
] 

teraz jeśli podam na wejście "SMITH" poniższy kod mi zwróci firmę o Id == 1 i wszyscy pracownicy będą w niej zawarci. Czyli na output dostanę również Jana Kowalskiego. Dlatego w Select jeszcze raz mam Where.

var result = _context.Companies.Include(c => c.Employees)
			.Where(c => c.Name.Contains(criteria.Keyword) ||
					    c.Employees.Any(e => e.FirstName.Contains(criteria.Keyword) ||
										e.LastName.Contains(criteria.Keyword)));
0

Chyba...

string[] keywords = new string[] { "ow", "ac","Nowak" };

var fs = new List<F>{
		new F{ 
			Id = 1, 
			Name = "Kowal", 
			Emps = new List<E>{
				new E{ Id = 1, FirstName="Jacek", LastName = "Placek"}, 
				new E{ Id = 1, FirstName="John", LastName = "Doe"}
			}
		}
	};
	
	var d = fs.Where(f =>
		
		keywords.Any(a=>f.Name.Contains(a) )
		
		|| f.Emps.Any(x=>keywords.Any(a=>x.FirstName.Contains(a) ))
		
	).Select(x=> 
		new F{
			Id = x.Id, 
			Name = x.Name, 
			Emps = x.Emps.Where(z => keywords.Any(a => z.FirstName.Contains(a) )).ToList()
		}
	);

1 użytkowników online, w tym zalogowanych: 0, gości: 1