как объединить поле в linq с sql

#linq-to-sql

#linq-to-sql

Вопрос:

Я хотел бы выполнить следующий sql-запрос в Linq to SQL.

  SELECT     TOP dbo.SiteDept.SiteDeptId, dbo.Site.SiteName   ' / '   dbo.Dept.DeptName AS SiteDeptName, dbo.SiteDept.SiteId, dbo.SiteDept.DeptId, 
                      dbo.Dept.DeptName
FROM         dbo.SiteDept INNER JOIN
                      dbo.Site ON dbo.SiteDept.SiteId = dbo.Site.SiteId INNER JOIN
                      dbo.Dept ON dbo.SiteDept.DeptId = dbo.Dept.DeptId
  

У меня есть контекст данных Linq to SQL как с объектом site и Dept, так и с объектом SiteDept, который связывает отделы с сайтами.

Я также добавил настраиваемое поле в частичном классе SiteDept для SiteDeptName .

Я думал о чем-то в следующих строках.

    public IEnumerable<SiteDept> GetAllSiteDepts()
    {
        var dataContext = new AtomWebDataContext(_connectionString);

        var allSiteDepts = from sd in dataContext.SiteDepts
                           join s in dataContext.Sites
                               on sd.SiteId equals s.SiteId
                           join d in dataContext.Depts
                               on sd.DeptId equals d.DeptId
                           select new SiteDept()
                                      {
                                          SiteDeptId = sd.SiteDeptId,
                                          SiteId = sd.SiteId,
                                          DeptId = sd.DeptId,
                                          SiteDeptName = s.SiteName   "/"   d.DeptName
                                      };
        return allSiteDepts;
    }
  

Однако я получаю сообщение «Явное построение объекта типа’GPSO.Repository.SiteDept’ в запросе не разрешено».

Каков наилучший способ добиться того, чего я хочу?

Комментарии:

1. Я думаю , что LINQ распознает string.Concat . Если нет, выберите как динамический объект, затем выполните новый запрос, allSiteDepts.AsEnumerable() и вы сможете использовать обычные средства.

Ответ №1:

Проблема в том, что SiteDept является одной из ваших сущностей, и она не позволит вам создать ее напрямую. Способ справиться с этим — настроить отношения между объектами и заставить LINQ to SQL извлекать их все, а затем использовать свойство частичного класса для заполнения нужного вам имени.

 public IEnumerable<SiteDept> GetAllSiteDepts()
{
    var dataContext = new AtomWebDataContext(_connectionString);

    var allSiteDepts = from sd in dataContext.SiteDepts
                       select s;

    return allSiteDepts.ToList();
}

// Site and Dept are EntityRefs on SiteDept and Site, respectively
public partial class SiteDept
{
     public string SiteDeptName
     {
         get { return this.SiteName   "/"   this.Site.Dept.Name; }
     }
}
  

Комментарии:

1. Я надеюсь, что SiteDept не используется в качестве DTO. Похоже, что это будет шоу ужасов, если ваша схема БД изменится…

2. @BradChristie — похоже, это объект первого класса, и вряд ли он изменится, если не будет проведен крупный рефакторинг базы данных (предположительно, также сопровождающийся организационными изменениями). Исправление этого свойства, вероятно, является наименьшей из ваших забот. Другой альтернативой было бы выбрать совершенно другую модель сущности, но, похоже, это не является целью.

3. Да, я использую siteDept в качестве DTO. Разве не стоит использовать объекты LINQ to SQL в качестве DTO.

4. @DavidKethel — Объекты LINQ to SQL по своей сути являются объектами доступа к данным / объектами домена. Если вы их измените (затем сохраните изменения в контексте данных), вы изменяете базу данных. Вы должны создавать DTO из объектов entity по мере необходимости.