Necromancing. Если используется поставщик LINQ, основанный на базе данных, может быть записано значительно более читаемое левое внешнее соединение:
from maintable in Repo.T_Whatever
from xxx in Repo.T_ANY_TABLE.Where(join condition).DefaultIfEmpty()
Если вы опустите DefaultIfEmpty()
, у вас будет внутреннее соединение.
Возьмите принятый ответ:
from c in categories
join p in products on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
Этот синтаксис очень сбивает с толку, и неясно, как это работает, когда вы хотите уйти, чтобы присоединиться к таблицам MULTIPLE.
Примечание. Следует отметить, что from alias in Repo.whatever.Where(condition).DefaultIfEmpty()
является таким же, как внешний-apply / left-join-lateral, который любой (не отсталый) оптимизатор базы данных отлично способен перевести в левое соединение , до тех пор, пока вы не вводите значения строк (например, фактическое внешнее применение). Не делайте этого в Linq-2-Objects (потому что при использовании Linq-to-Objects нет DB-оптимизатора).
Подробный пример
var query2 = (
from users in Repo.T_User
from mappings in Repo.T_User_Group
.Where(mapping => mapping.USRGRP_USR == users.USR_ID)
.DefaultIfEmpty() // <== makes join left join
from groups in Repo.T_Group
.Where(gruppe => gruppe.GRP_ID == mappings.USRGRP_GRP)
.DefaultIfEmpty() // <== makes join left join
// where users.USR_Name.Contains(keyword)
// || mappings.USRGRP_USR.Equals(666)
// || mappings.USRGRP_USR == 666
// || groups.Name.Contains(keyword)
select new
{
UserId = users.USR_ID
,UserName = users.USR_User
,UserGroupId = groups.ID
,GroupName = groups.Name
}
);
var xy = (query2).ToList();
При использовании с LINQ 2 SQL он хорошо переведёт на следующий очень читаемый SQL-запрос:
SELECT
users.USR_ID AS UserId
,users.USR_User AS UserName
,groups.ID AS UserGroupId
,groups.Name AS GroupName
FROM T_User AS users
LEFT JOIN T_User_Group AS mappings
ON mappings.USRGRP_USR = users.USR_ID
LEFT JOIN T_Group AS groups
ON groups.GRP_ID == mappings.USRGRP_GRP
Редактировать:
См. Также & quot; Конвертировать запрос SQL Server в запрос Linq & quot; для более сложного примера.
Кроме того, если вы делаете это в Linq-2-Objects (вместо Linq-2-SQL), вы должны сделать это старомодно (потому что LINQ to SQL правильно это переводит для присоединения операции, но над объектами этот метод заставляет полностью сканировать и не использует поиск по индексу, почему ...):
var query2 = (
from users in Repo.T_Benutzer
join mappings in Repo.T_Benutzer_Benutzergruppen on mappings.BEBG_BE equals users.BE_ID into tmpMapp
join groups in Repo.T_Benutzergruppen on groups.ID equals mappings.BEBG_BG into tmpGroups
from mappings in tmpMapp.DefaultIfEmpty()
from groups in tmpGroups.DefaultIfEmpty()
select new
{
UserId = users.BE_ID
,UserName = users.BE_User
,UserGroupId = mappings.BEBG_BG
,GroupName = groups.Name
}
);
Предположение, что это - TCP (а не UDP) порт, который Вы пытаетесь использовать:
На самом сервере, используйте netstat -an
для проверки для наблюдения, какие порты слушают.
Снаружи, просто используйте telnet host port
(или telnet host:port
в системах Unix), чтобы видеть, отказывают ли соединению, принимают, или тайм-ауты.
На том последнем тесте, затем в целом:
На Windows 7 или Windows Vista опция по умолчанию 'telnet' не распознана как внутренняя или внешняя команда, действующая программа или пакетный файл. Для решения этого просто включите его: Нажмите *, Запускаются ** → Панель управления → Программы → Включают или выключают Windows features . В списке прокрутите вниз и выберите Клиент Telnet и нажмите хорошо .
Вы хотите инструмент для того, чтобы сделать его? Существует веб-сайт в http://www.canyouseeme.org/ . Иначе Вам нужен некоторый другой сервер для призывания обратно Вас, чтобы видеть, открыт ли порт...