Несколько левых соединений LINQ-to-entity - PullRequest
2 голосов
/ 05 октября 2010

У меня есть 3 таблицы:

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

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

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

Таким образом, отношения показывают, что у нас есть дилерские центры с несколькими местоположениями (например: Weed Chevrolet из PA, Weed Chevrolet из Нью-Джерси), а затем у каждого местоположения есть свои контакты(Пример: менеджеры локации PA, менеджеры локации NJ).Мне нужно объединить 3 таблицы вместе.Вот что у меня есть:

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
               }

Когда я пытаюсь связать результаты с BindingSource, а затем с DataGridView, я получаю следующую ошибку:

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

Что это может быть?Я новичок в операторах JOIN в LINQ, поэтому я уверен, что делаю что-то не так.

РЕДАКТИРОВАТЬ: в базе данных есть данные, поэтому результаты не должны быть нулевыми, просто чтобы уточнить

Ответы [ 3 ]

12 голосов
/ 05 октября 2010

Вы были близки, но я обнаружил, что вам нужно преобразовать его из LINQ-To-Entities в LINQ-To-Objects.Сначала я должен был разыграть сущности, используя AsEnumerable(), а затем ToList().Это позволило мне использовать такие функции, как ToString() и String.Format().Спасибо, что привели меня в правильном направлении.Вот окончательный код:

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;
2 голосов
/ 05 октября 2010

Поскольку ваши результаты равны IQueryable , EF попытается выполнить приведение на стороне хранилища данных, и оно не будет работать, поскольку приведение работает только со скалярными типами.Вы должны вызывать ToList () для результатов следующим образом:

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();
0 голосов
/ 15 сентября 2015
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();
...