ASP.NET MVC 2: сущность Linq to SQL с отношением ForeignKey и странностью ModelBinder по умолчанию - PullRequest
1 голос
/ 30 апреля 2010

Еще раз у меня проблемы с Linq to Sql и MVC Model Binder.

У меня есть сгенерированные классы Linq to Sql, чтобы проиллюстрировать их, они выглядят примерно так:

public class Client
{
    public int ClientID { get; set; }
    public string Name { get; set; }
}

public class Site
{
    public int SiteID { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int UserID { get; set; }
    public string Name { get; set; }
    public int? ClientID { get; set; }
    public EntityRef<Client> Client { get; set; }
    public int? SiteID { get; set; }
    public EntityRef<Site> Site { get; set; }
}

«Пользователь» имеет отношения с «Клиентом» и «Сайтом». , Класс User имеет обнуляемые ClientID и SiteID, поскольку пользователи с правами администратора не связаны с Клиентом или Сайтом.

Теперь у меня есть представление, где пользователь может редактировать объект «Пользователь», представление имеет поля для всех свойств «Пользователь». Когда форма отправлена, в моем UserController вызывается соответствующее действие «Сохранить»:

public ActionResult Save(User user, FormCollection form)
{
    //form['SiteID'] == 1
    //user.SiteID == 1

    //form['ClientID'] == 1
    //user.ClientID == null
}

Проблема в том, что ClientID никогда не устанавливается, он всегда равен нулю, даже если значение находится в FormCollection.

Чтобы выяснить, что происходит не так, я установил точки останова для геттеров и установщиков ClientID и SiteID в классах, сгенерированных конструктором Linq to Sql. Я заметил следующее: Идентификатор SiteID устанавливается, затем устанавливается ClientID, но затем свойство Client EntityRef устанавливается со значением NULL, что, в свою очередь, также устанавливает для ClientID значение NULL! Я не знаю, почему и что пытается установить свойство Client, потому что никогда не вызывается установщик свойства Site, вызывается только установщик Client.

Установка ClientID из FormCollection вручную следующим образом:

user.ClientID = int.Parse(form["ClientID"].ToString());

выдает исключение ForeignKeyReferenceAlreadyHasValueException, поскольку оно уже было установлено в null ранее. Единственный обходной путь, который я нашел, - это расширение созданного частичного класса User с помощью пользовательского метода:

Client = default(EntityRef<Client>)

но это не удовлетворительное решение. Я не думаю, что это должно работать так?

Пожалуйста, просветите меня кого-нибудь. Пока что Linq to Sql сводит меня с ума!

С наилучшими пожеланиями

1 Ответ

1 голос
/ 29 июля 2012

Я только что выполнил ту же проблему с MVC 3. Я думаю, что это происходит, потому что связыватель модели устанавливает все открытые свойства класса модели при его создании. Таким образом, он устанавливает user.ClientID в 1, а затем user.Client в null (потому что его нет в коллекции форм). И после этого значение user.ClientID тоже становится null.
Поэтому вам просто нужно исключить свойство Client класса User из привязки следующим образом:

public ActionResult Save([Bind(Exclude="Client")]User user, FormCollection form)

Это сработало для меня.

...