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"