Linq To SQL без явных внешних отношений
Я работаю с несколькими устаревшими таблицами, которые имеют отношения, но эти отношения не были явно заданы как первичные/внешние ключи. Я создал файл .dbml, используя "Linq To Sql Classes" и установил правильную ассоциацию Case.CaseID = CaseInfo.CaseID. Мой итоговый класс - 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 Entity Data Model создать класс Data Context, но еще не пробовал, и хотел бы посмотреть, буду ли я тратить свое время или я должен пойти другим путем, Любые советы, ссылки, помощь будут наиболее оценены.
Ответы
Ответ 1
Вернитесь к дизайнеру и проверьте правильность установки отношения. Вот один пример реальной жизни: у BillStateMasters есть свойство CustomerMasters1 (клиенты для государства):
alt text http://i43.tinypic.com/ohl00l.jpg
Ps. именование очищается...
Обновление 1: Вам также необходимо убедиться, что обе таблицы имеют первичный формат. Если первичный ключ не определен в базе данных (и не может быть определен по какой-либо причине), обязательно определите их в дизайнере. Откройте свойства столбца и установите его как первичный ключ. Тем не менее, отслеживание объектов также не будет работать, если у вас нет первичного ключа для объекта, который для удаления означает, что он молча не обновляет объект. Поэтому обязательно просмотрите все сущности и сделайте их все с помощью первичного ключа (как я уже сказал, если он не может быть на db, а затем на дизайнере).
Ответ 2
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};
my "join" linq немного ржавый, но выше должно быть близко к тому, что вы после.
Ответ 3
Установлена ли ассоциация "Один на один" или "Один на много"? Если у вас установлена связь от одного до многих, то у вас есть EntitySet, а не EntityRef, и вам нужно будет использовать предложение where для зависимого набора, чтобы получить правильное значение. Я подозреваю, что вам нужны отношения "один к одному", которые не являются стандартными. Попробуйте изменить его на один на один и посмотреть, можете ли вы построить запрос.
Примечание. Я просто догадываюсь, потому что вы на самом деле не сказали нам, что такое "проблема" на самом деле.
Ответ 4
Ваш запрос выглядит корректно и должен возвращать набор результатов запроса объектов Case.
Итак... в чем проблема?
(Edit) Моя проблема заключается в том, что CaseInfo недоступен в случаях... т.е. c.CaseInfo не существует, где я предполагая, что если бы явный первичный/внешний ключ отношения.
Что значит "недоступно"? Если вы создали ассоциацию в дизайнере, как вы говорите, тогда запрос должен генерировать SQL-код по строкам
SELECT [columns]
FROM Case INNER JOIN CaseInfo
ON Case.CaseID = CaseInfo.CaseID
WHERE CaseInfo.CaseInfoMeta = 'some value'
Отлаживается ли ваш запрос linq для получения SQL-данных? Что он возвращает?
Ответ 5
Несколько вещей, которые вы можете попробовать:
Проверьте свойства ассоциации. Убедитесь, что свойство Parent было создано как общедоступное. Он делает это по умолчанию, но что-то может измениться.
Поскольку вы не получаете CaseInfo на C, попробуйте ввести его в другом направлении, чтобы узнать, получаете ли вы ci.Case с intellisense.
Удалите и воссоздайте связь вместе.
Там что-то очень основное происходит неправильно, если члены ребенка не появляются. Лучше всего удалить dbml и воссоздать все это.
Если все остальное не работает, переключитесь на NHibernate.:)
Ответ 6
Это С#? Я думаю, вам нужно ==
вместо = в этой строке:
where c.CaseInfo.CaseInfoMeta = "some value"
должен читать
where c.CaseInfo.CaseInfoMeta == "some value"
Ответ 7
После нескольких тестов я уверен, что отношения FK требуются в БД независимо от того, какие ассоциации создаются в Linq-to-SQL. т.е. если вы не указали их явно в БД, вам нужно будет сделать соединение вручную.