Linq to SQL без явных связей внешнего ключа
Я работаю с несколькими устаревшими таблицами, которые имеют отношения, но эти отношения явно не были установлены как первичные/внешние ключи. Я создал .dbml-файл с использованием "Linq to Sql Classes"и установил правильный случай.CaseID = CaseInfo.Ассоциация наблюдения. Мой результирующий класс-CasesDataContext.
мои таблицы (один ко многим):
Case
------------------
CaseID (int not null)
MetaColumn1 (varchar)
MetaColumn2 (varchar)
MetaColumn3 (varchar)
...
CaseInfo
------------------
CaseInfoID (int)
CaseID (int nulls allowed)
CaseInfoMeta (varchar)
...
Я новичок в LinqToSQL и у меня возникли проблемы..
CasesDataContext db = new CasesDataContext();
var Cases = from c in db.Cases
where c.CaseInfo.CaseInfoMeta == "some value"
select c;
(Edit) моя проблема это CaseInfo или CaseInfos не доступен в качестве участника обращений.
Я слышал от коллеги, что я мог бы попробовать ADO.Net модель данных сущности для создания моего класса контекста данных, но еще не пробовал и хотел посмотреть, буду ли я тратить свое время или должен пойти другим маршрутом. Любые советы, ссылки, помощь будут наиболее оценены.
7 ответов
вернитесь к конструктору и проверьте, правильно ли настроено отношение. Вот один пример реальной жизни, с BillStateMasters имеют свойство" CustomerMasters1 " (клиенты для государства): alt текст http://i43.tinypic.com/ohl00l.jpg
Ps. именование очищается ...
обновление 1: Вам также необходимо убедиться, что обе таблицы имеют первичное определение. Если первичный ключ не определен в базе данных (и не может быть определен для любой причина), обязательно определите их в конструкторе. Откройте свойства столбца и задайте его в качестве первичного ключа. Тем не менее, отслеживание сущностей также не будет работать, если у вас нет первичного ключа для сущности, что для удаления означает, что он молча не обновляет сущность. Поэтому обязательно просмотрите все объекты и получите их все с первичным ключом (как я уже сказал, если он не может быть в БД, то в конструкторе).
CasesDataContext db = new CasesDataContext();
var Cases = from c in db.Cases
join ci in db.CaseInfo on
ci.ID equals c.InfoID
where ci.CaseInfoMeta == "some value"
select new {CASE=c, INFO=ci};
мой" join " linq немного ржавый, но выше должно приблизиться к тому, что вам нужно.
установлена ли ассоциация один к одному или один ко многим? Если у вас установлена связь один ко многим, то у вас есть EntitySet, а не EntityRef, и вам нужно будет использовать предложение where в зависимом наборе, чтобы получить правильное значение. Я подозреваю, что вы хотите отношения один к одному, что не является значением по умолчанию. Попробуйте изменить его на один к одному и посмотреть, сможете ли вы построить запрос.
Примечание: я просто догадываюсь, потому что вы на самом деле не сказали нам, что " проблема" действительно быть.
ваш запрос выглядит правильно и должен возвращать результирующий набор объектов Case.
Так... в чем проблема?
(Edit) моя проблема в том, что CaseInfo не доступен в разделе дела... т. е. c.Казеинфо не существует там, где я. предполагая, что это было бы, если бы были явный первичный / внешний ключ отношения.
что вы подразумеваете под "недоступно"? Если вы создали ассоциацию в конструкторе, как вы говорите вы сделали, то запрос должен генерировать SQL что-то вроде
SELECT [columns]
FROM Case INNER JOIN CaseInfo
ON Case.CaseID = CaseInfo.CaseID
WHERE CaseInfo.CaseInfoMeta = 'some value'
вы отладили свой запрос linq, чтобы получить SQL, сгенерированный еще? Что она возвращает?
пара вещей, которые вы можете попробовать:
Проверьте свойства ассоциации. Убедитесь, что родительское свойство создано как Public. Он делает это по умолчанию, но что-то может измениться.
Так как вы не получаете CaseInfo на C, попробуйте ввести его в другом направлении, чтобы увидеть, если вы получаете ci.Случай с intellisense.
удалить и воссоздать ассоциацию все вместе.
Что-то очень основное идет не так, если ребенок члены не появляются. Возможно, лучше всего удалить dbml и воссоздать все это.
Если все остальное не удается, переключитесь на NHibernate. :)
после нескольких тестов я уверен, что отношения FK требуются в БД независимо от того, какие ассоциации создаются в Linq-to-SQL. т. е. если у вас нет их явно установленных в БД, то вам придется сделать соединение вручную.
это c#? Я думаю, вам нужно ==
вместо = в этой строке:
where c.CaseInfo.CaseInfoMeta = "some value"
следует читать
where c.CaseInfo.CaseInfoMeta == "some value"