Измените два ряда одновременно - PullRequest
2 голосов
/ 08 июля 2010

Контекст: ASP.NET MVC 2.0, Linq-to-Sql, .Net 3.5, IIS7, MS SQL 2008

Я работаю на сайте фанатов игр.

У меня естьтаблица выглядит следующим образом:

ToonId int (primary key)
RealmId (FK into Realms table)
OwnerId int (FK into Users table)
ToonName nvarchar(50)
IsMain bit

То есть один пользователь может иметь несколько мультяшек в нескольких сферах (или на серверах), но ровно один мультяшный знак должен быть помечен как основной на пользователя в каждой области (только для областей, гдепо крайней мере один toon).

Предположим, у меня есть два toon (в одной области): Foo (помечен как основной)
и Bar (не основной)

Я хочу изменить свойmain, и для этого я делаю что-то вроде: Foo.IsMain = false Bar.IsMain = true

Я использую Linq-to-SQL.

Вопрос: как я могу выполнить указанный переход, не входя в состояние, когда у меня есть более одного или ноль главных мультов.

Примечание: у меня есть материализованное представление (отфильтрованное по IsMain = 1), которое определяет составной ключ (OwnerId,RealmId), поэтому, когда я делаю мейн-мун переход, я получаю исключение «нарушение уникального ключа» из этого материализованного представления.

I попытался использовать транзакцию, но я все еще получаю исключение для 'db.SubmitChanges ()'.

Вариант 2: Я подозреваю, что у меня есть изъян в дизайне базы данных (как называется этот недостаток?).Должен ли я создать таблицу сопоставления?

OwnerId, RealmId -> ToonId

1 Ответ

1 голос
/ 08 июля 2010

Вопрос 1

Вам необходимо использовать транзакции.

 DBDataContext db = new DBDataContext();
 using (TransactionScope ts = new TransactionScope())
 {
     try
     {
         Toon toon1 = db.Toons.First(p => p.ToonId == 4);
         Toon toon2 = db.Toons.First(p => p.ToonId == 5);
         toon1.IsMain = false;
         toon2.IsMain = true;
         db.SubmitChanges();
         ts.Complete();
     }
     catch (Exception e)
     {
        Console.WriteLine(e.Message);
     }
}

Вопрос 2

Вы должны подумать о своем дизайне немного больше.

Шаг 1

Это игрок, у которого есть основной Toon, поэтому я бы поместил MainToonId на ваш стол пользователей и удалил ваш IsMain с вашего стола Toon.

После этого вашими таблицами будут Пользователи (Existing Stuff, MainToonId), Realms (Existing Stuff), Toons (ToonId, RealmId, OwnerId, ToonName)

Шаг 2

Как вы и предполагали, вы, вероятно, могли бы переместить ссылку Realm / Owner / Toon в свою собственную таблицу (или даже таблицы ToonOwner и ToonRealm). Информация о ссылке связана с Toon, но не является идентифицирующей частью того, чтобы быть Toon. Разрешение этого «недостатка» - нормализация, и база данных, которая нуждается в ней, описывается как «нуждающаяся в нормализации». Однако этот шаг полностью необязателен в этом случае и может быть чрезмерно нормализующим для ваших нужд.

Если вы использовали одну таблицу соответствия, новая таблица будет содержать PK из 3 значений, комбинированных (если вы натуральный ключ), в противном случае стандартное PK и УНИКАЛЬНОЕ для 3 значений (если вы не натуральный) кейер). У вас также должен быть УНИКАЛЬНЫЙ на ToonId, поскольку каждый Toon предположительно может принадлежать только одному Царству или Владельцу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...