ForeignKeyReferenceAlreadyHasValueException при создании поисков с использованием LINQ to SQL - PullRequest
5 голосов
/ 16 сентября 2010

Я новичок в C # и .NET, и я только начал изучать LINQ to SQL, мне это нравится.Но .. Я нашел эту очень раздражающую вещь об этом.Реализация lookUps очень сложна из-за «ForeignKeyReferenceAlreadyHasValueException»!Нет простого простого способа сделать это!Я заметил, что если я удаляю все ассоциации между сущностями LINQ, проблема «ForeignKeyReferenceAlreadyHasValueException» больше не будет!Я планирую разработать небольшие приложения для баз данных WinForms, содержащие не более 100 таблиц ...

Поэтому мой вопрос:

Что я потеряю / рискую, если использую LINQ2SQL, но удаляю всеассоциации между сущностями LINQ и сохранить отношения в базе данных?

Ответы [ 3 ]

5 голосов
/ 16 сентября 2010

В основном вы потеряете поддержку запросов, отложенную загрузку, IntelliSense и т. Д. Например, у вас не будет таких вещей, если вы удалите связь между Пользователи и Вопросы :

from u in context.Users
where u.Questions.Count > 2
select u;

Смысл LINQ состоит в том, чтобы предоставить вам все конструкции, необходимые для реализации модели реляционной базы данных в вашем коде C #, что позволяет вам запрашивать эту модель. Если вы удалите все ассоциации / отношения, LINQ to SQL теряет свою цель.

Относительно Исключение Вы получили:

Если свойство ассоциации присвоить значение, которое вы не можете изменить поле внешнего ключа больше, вы должны изменить отношения, изменив собственность ассоциации. За Например, используя Customer и Order from Пример базы данных Northwind. Если Свойство «Заказчик» в заказе присвоить значение, которое вы больше не можете вручную изменить CustomerID заказа поле, так как оно должно соответствовать PK клиент. Вы можете, однако, изменить свойство «Клиент» напрямую, назначив его новым клиентом пример. Это действие будет автоматически обновлять идентификатор клиента поле для сопоставления. Мэтт Уоррен (архитектор LINQ to SQL)

Это то, что вам нужно сделать, чтобы решить вашу проблему:

LINQ to SQL ForeignKeyReferenceAlreadyHasValueException error

Для LookUps и LINQ, сделайте это:

LINQ, Lookups, ForeignKeyReferenceAlreadyHasValueException

Используйте этот код, например, при связывании выпадающего списка:

With cboCategory 
.DataSource = From Category In db.Categories Order By Category.Name
              Select Category 
.DisplayMember = "Name" 
.ValueMember = "ID"    don't set value member: http://tinyurl.com/d9etoy 
.DataBindings.Add(New Binding("SelectedItem", ItemBindingSource, "Category")) 
End With 
5 голосов
/ 06 декабря 2010

Вы делаете неправильные изменения в отношениях. Если у вас есть объект Order с объектом Customer, прикрепленным к нему в качестве участника, вы можете просмотреть информацию о клиенте следующим образом:

var order = db.Orders.Single(x => x.ID == 40);
var cusName = order.Customer.GetFullCustomerName();

Однако, если вам нужно изменить этого Клиента для этого Заказа в базе данных, вы не можете просто установить в поле Order.CustomerID новый идентификатор. Это вызовет ошибку ForeignKeyReferenceAlreadyHasValueException.

// wrong way...
order.CustomerID = 45; // id of the new customer
// BOOOOM goes the error here.

// right way...
order.Customer = db.Customer.Single(x => x.ID == 45);

db.SubmitChanges();

Другими словами, когда вы извлекаете Order.Customer из базы данных, вы не можете вручную изменить связанного клиента, просто изменив внешний ключ для этой строки в таблице Orders. Вы должны установить член order.Customer в качестве другого действующего объекта Customer, а затем откатить изменения обратно в базу данных.

1 голос
/ 16 сентября 2010

То, что вы теряете, это, конечно, отношения. Обычно LINQ to SQL автоматически заполняет полезные коллекции, которые абстрагируют отношения, например:

var query = db.Orders.Where(o => o.Products.Count() > n);
                                   ^^^^^^^^
                           // You would lose this

Затем вам придется написать это более окольным путем, например,

var query = db.Orders.Where(o =>
                db.OrderProducts.Count(p => p.ProductId == o.ProductId) > n);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...