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. т.е. если вы не указали их явно в БД, вам нужно будет сделать соединение вручную.