2 votes

Multiple Left Join LINQ-to-entities

J'ai 3 tables :

Dealerships
------------
ID, Name, Website

Locations
------------
ID, DealershipID, Address, Ect.

Contacts
------------
ID, LocationID, Name, Ect.

La relation montre donc que nous avons des concessionnaires qui ont plusieurs sites (exemple : Weed Chevrolet of PA, Weed Chevrolet of NJ) et que chaque site a ses propres contacts (exemple : Managers du site PA, Managers du site NJ). J'ai besoin de joindre les 3 tables ensemble. Voici ce que j'ai :

var results = from d in entities.dealerships
              join l in entities.locations on d.ID equals l.DealershipID
              join c in entities.contacts on l.ID equals c.LocationID
              select new
              {
                  Name = d.Name,
                  Website = d.Website,
                  Address = l.Address + ", " + l.City + ", " + l.State + " " + l.Zip,
                  Contact = c.FirstName + " " + c.LastName,
                  WorkPhone = c.WorkPhone,
                  CellPhone = c.CellPhone,
                  HomePhone = c.HomePhone,
                  Email = c.Email,
                  AltEmail = c.AltEmail,
                  Sells = l.Sells
               }

Quand j'essaie de lier résultats à une BindingSource, puis à un DataGridView, je reçois l'erreur suivante :

Unable to cast the type 'System.Nullable`1' to type 'System.Object'.
LINQ to Entities only supports casting Entity Data Model primitive types.

Qu'est-ce que ça peut être ? Je suis novice en matière d'instructions JOIN dans LINQ, donc je suis sûr que je fais quelque chose de mal.

EDIT : Il y a des données dans la base de données donc les résultats ne devraient pas être nuls, juste pour clarifier.

12voto

Cris McLaughlin Points 620

Vous étiez proche mais j'ai découvert que vous devez le convertir de LINQ-To-Entities en LINQ-To-Objects. D'abord, j'ai dû convertir les entités en utilisant AsEnumerable() puis utiliser ToList() . Cela m'a permis d'utiliser des fonctions comme ToString() y String.Format() . Merci de me guider dans la bonne direction. Voici le code final :

var query = from d in entities.dealerships
            from l in entities.locations.Where(loc => loc.DealershipID == d.ID).DefaultIfEmpty()
            from c in entities.contacts.Where(cont => cont.LocationID == l.ID).DefaultIfEmpty()
            where d.Keywords.Contains(keywords) || l.Keywords.Contains(keywords) || l.Sells.Contains(keywords) || c.Keywords.Contains(keywords)
            select new
            {
                Dealership = d,
                Location = l,
                Contact = c
            };

var results = (from r in query.AsEnumerable()
               select new
               {
                   Name = r.Dealership.Name,
                   Website = r.Dealership.Website,
                   Contact = r.Contact.FirstName + " " + r.Contact.LastName,
                   Address = r.Location.Address + ", " + r.Location.City + ", " + r.Location.State + " " + r.Location.Zip,
                   WorkPhone = r.Contact.WorkPhone,
                   CellPhone = r.Contact.CellPhone,
                   Fax = r.Contact.Fax,
                   Email = r.Contact.Email,
                   AltEmail = r.Contact.AltEmail,
                   Sells = r.Location.Sells
               }).ToList();

bindingSource.DataSource = results;

2voto

Morteza Manavi Points 20486

Puisque vos résultats sont IQueryable Dans ce cas, EF essaiera d'effectuer un cast du côté du magasin de données et cela ne fonctionnera pas car le cast ne fonctionne qu'avec des types scalaires. Vous devez appeler ToList() sur l'objet résultats comme ça :

var results = (from d in entities.dealerships
              join l in entities.locations on d.ID equals l.DealershipID
              join c in entities.contacts on l.ID equals c.LocationID
              select new
              {
                  Name = d.Name,
                  Website = d.Website,
                  Address = l.Address + ", " + l.City + ", " + l.State + " " + l.Zip,
                  Contact = c.FirstName + " " + c.LastName,
                  WorkPhone = c.WorkPhone,
                  CellPhone = c.CellPhone,
                  HomePhone = c.HomePhone,
                  Email = c.Email,
                  AltEmail = c.AltEmail,
                  Sells = l.Sells
               }).ToList();

0voto

Sathish RKS Points 1
var EmplistDriver = (from a in data
                     join b in db.DesignationDetails on a.DesignationID equals b.DesignationDetailID into EmployeeBonus
                     from b in dataBonus.DefaultIfEmpty()

                     join x in db.EmployeeCommission on a.EmployeeDetailID equals x.EmployeeDetailID into EmployeeCommission
                     from x in dataComm.DefaultIfEmpty()

                     join c in db.EmployeeAdvance on a.EmployeeDetailID equals c.FKEAEmployeeID

                     join d in db.EmployeeAllowance on a.EmployeeAllowanceID equals d.EmployeeAllowanceID
                     join e in dataAtt on a.EmployeeDetailID equals e.EmployeeDetailID

                     join f in dataDri on a.EmployeeDetailID equals f.EmployeeDetailID
                     join h in db.ProjectAllocation on f.FKAllocationID equals h.PKAllocationID

                     join i in db.ProjectDetails on h.FKProjectDetailID equals i.ProjectDetailID

                     where a.IsActive == true && c.EAIsActive == true && d.IsActive == true && e.EAIsActive == true && h.IsActivity == true

                     select new
                     {
                         c.BalanceAmount,
                         c.BalanceDue,
                         d.FoodAllowance,
                         i.DriverBasicSalary,
                         d.OtherAllowance,
                         d.AccommodationAllowance,
                         e.EABasicWorktime,
                         BonusAmount = (b.BonusAmount == null ? 0 : b.BonusAmount),
                         CommissionAmount = (x.CommissionAmount == null ? 0 : x.CommissionAmount),
                         TotalOverTime,
                         TotalHr

                     }).FirstOrDefault();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X