Pytanie wybierz konkretne kolumny, gdy używasz instrukcji include do struktury encji


Kiedy potrzebuję relacji hierarchicznej (parent-child), zazwyczaj używam instrukcji Include w moim zapytaniu EF.

Przykład:

DbContext.Customers.Include("Projects");

To jest w porządku, ale obiekty Klienci i Projekty zawsze przywracają wszystkie kolumny.

Wiem, że poniższe zapytanie spowoduje przywrócenie określonych kolumn w tabeli nadrzędnej, ale próbuję również przywrócić tylko określone kolumny w tabeli podrzędnej. Jeśli używam intellisense w projektach, jest to oczywiście kolekcja i nie daje konkretnych właściwości do wyboru.

from c in Customers
let Projects = c.Projects.Where (p => p.Notes != null)
where Projects.Any()
select new
{
    c.UserName,
    Projects
}

Próbowałem doprecyzować zapytanie do poniższego kodu, ale jak widzisz, encja Projekty jest dziecko podmiot klientów i dlatego nie ma konkretnej kolumny do wyboru w zapytaniu. To oczywiście jest kolekcja.

Czy istnieje sposób, aby przywrócić tylko określone kolumny w każdym z podmiotów przy użyciu Uwzględnij w zapytaniu?

Zwróć uwagę, że mój model YeagerTechDB.ViewModels.Customers składa się ze wszystkich kolumn znajdujących się w jednostkach Customer i Project.

public List<YeagerTechDB.ViewModels.Customers> GetCustomerProjects()
        {
            try
            {
                using (YeagerTech DbContext = new YeagerTech())
                {
                    var customer = DbContext.Customers.Include("Projects").Select(s =>
                        new YeagerTechDB.ViewModels.Customers()
                        {
                            CustomerID = s.CustomerID,
                            ProjectID = s.ProjectID,
                            UserName = s.UserName,
                            Name = s.Projects.,
                        });

                     return customer.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

ODPOWIEDŹ # 1 DLA 1 PODMIOTY DZIECI

from c in Customers
let Projects = c.Projects.Where (p => p.Notes != null)
where Projects.Any()
select new
{
    c.UserName,
    Projects
}

ODPOWIEDŹ # 2 DLA 2 PODMIOTÓW DZIECIĘCYCH

from c in Customers
let highValueP =
    from p in c.Projects
    where p.Quote != null
    select new { p.ProjectID, p.Name, p.Quote }
where highValueP.Any()
from p in Projects
let highValuet =
    from t in p.TimeTrackings
    where t.Notes != null
    select new { t.ProjectID, t.Notes }
where highValuet.Any()
select new 
{
    c.CustomerID,
    Projects = highValueP,
    TimeTrackings = highValuet
}

Edytuj # 3 enter image description here


11
2018-04-04 16:54


pochodzenie




Odpowiedzi:


Sprawdź to połączyć po więcej szczegółów. W skrócie, sztuczka polega na użyciu. Wybierz () i anonimowy typ, aby ograniczyć kolumny, które chcesz. W poniższym przykładzie najpierw Select () faktycznie robi to:

var results = context.Products
        .Include("ProductSubcategory")
        .Where(p => p.Name.Contains(searchTerm)
                    && p.DiscontinuedDate == null)
        .Select(p => new
                        {
                            p.ProductID,
                            ProductSubcategoryName = p.ProductSubcategory.Name,
                            p.Name,
                            p.StandardCost
                        })
        .AsEnumerable()
        .Select(p => new AutoCompleteData
                            {
                                Id = p.ProductID,
                                Text = BuildAutoCompleteText(p.Name,
                                    p.ProductSubcategoryName, p.StandardCost)
                            })
        .ToArray();

9
2018-04-04 17:50



To ma sens ... Dzięki ... Czy ty lub ktoś inny mógł mi powiedzieć, co jest nie tak z EDIT # 3 w mojej odpowiedzi? Twoja odpowiedź i moje odpowiedzi # 1 i # 2 działają dobrze dla anonimowych typów, ale co jeśli chcę włożyć do modelu? - sagesky36
@ sagesky36, trochę późno, ale myślę, że brakuje ci "nowego" klucza w klauzuli Select. - Piyey
Co jeśli włączasz wiele dzieci do Products? NA PRZYKŁAD. Jeśli zamiast ProductSubcategory miałeś ProductSubCategories i chcesz wybrać tylko nazwę każdej z tych kategorii. - xr280xr
To "działa", ale powoduje zapytanie dla jednego elementu nadrzędnego zamiast łączenia. - Timothy Gonzalez