Подтвердить что ты не робот

Архитектура контроллера VS 2013 не работает для модели ApplicationUser (несколько наборов объектов для каждого типа не поддерживаются)

В RTM VS 2013, проект MVC 5 с EF 6, я попытался подстроить контроллер на основе ApplicationUser (по умолчанию с индивидуальной аутентификацией учетных записей). Оба ApplicationUser и IdentityUser отображаются в таблицу Users. Мастер открывает контекстный файл для редактирования и пытается добавить новый набор db для ApplicationUser (ApplicationUsers), а затем с ошибкой:

Unable to retrieve metadata for ApplicationUser. Multiple object sets per type are not supported. The object sets ApplicationUsers and Users can both contain instances of type ApplicationUser В решении нет ссылки на экземпляр ApplicationUsers.

Это известная проблема? Можно ли запустить строительные леса с помощью командной строки с параметрами (от PMC)? Примечание: scaffolding также добавляет дополнительный db, заданный для класса контекста, если я укажу модель, которая ссылается на ApplicationUser (приложение работает, если я удалю его и исправлю ссылки в генератор-контроллере).

4b9b3361

Ответ 1

Ого. Я действительно удивляюсь, что никто в действительности не дошел до корня этого, а вместо этого просто рекомендует обходные пути.

IdentityDbContext уже содержит свойство:

`public virtual IDbSet<TUser> Users { get; set; }

Когда вы подклассом IdentityDbContext создаете свой собственный специфический для приложения контекст, вы должны указать, какой класс удовлетворяет стандарту TUser. По умолчанию:

public ApplicationDbContext : IdentityDbContext<ApplicationUser>

Что означает, что вы функционально имеете свойство уже через наследование в виде:

public IDbSet<ApplicationUser> Users { get; set; }

Если вы затем добавите другое свойство в свой специфичный для приложения контекст, например:

public DbSet<ApplicationUser> ApplicationUsers { get; set; }

Теперь у вас есть тот же объект, который отслеживается двумя DbSet s, и вы получаете эту ошибку. Решение? Просто не добавляйте свой собственный DbSet для ApplicationUser. Нет необходимости переименовывать или переопределять что-либо.

Ответ 2

Краткая версия: переименуйте класс ApplicationUser в User.

Я столкнулся с этой проблемой около месяца, и мне не повезло... до сих пор!

Вначале я думал, что это вопрос предварительного просмотра, но после того, как я остался в RTM вместе с последними библиотеками, я стал невероятно раздраженным, так как эта проблема также сохранялась в Migrations.

Однако IdentityDbContext, согласно сообщению об ошибке, похоже, создает два DbSets: ApplicationUsers и Users. Мы хотим, чтобы пользователи смотрели исходный код:

public class IdentityDbContext<TUser> : DbContext where TUser : Microsoft.AspNet.Identity.EntityFramework.IdentityUser
{
    ...
    public virtual IDbSet<TUser> Users { get; set; }
    ...
}

Из этого мы (и движок леса, и движок миграции) должны видеть только "Пользователи", а не "Приложения".

Чтобы исправить эту ситуацию, вам потребуется настроить класс приложения для учетной записи для этой довольно странной ошибки. Просто переименуйте класс ApplicationUser в User:

using Microsoft.AspNet.Identity.EntityFramework 
...
public class ApplicationUser : IdentityUser
{
    Your Stuff
}

To:

using Microsoft.AspNet.Identity.EntityFramework 
...
public class User: IdentityUser
{
    Your Stuff
}

Попытка снова подняться. Если вы получите еще одну ошибку по строкам класса, не можете найти, сохранить проект, закрыть VS2013, повторно открыть VS2013, загрузить проект, перестроить проект и, наконец, попытаться выполнить эшафот. IdentityDBContext больше не должен создавать фиктивный объект DBSet "ApplicationUsers", заставляя как Entity Migrations, так и Scaffolding выдавать эти ошибки.

Надеюсь, это поможет!

P.S. Любое сделанное сопоставление не должно влиять на эту проблему, поэтому вы должны иметь возможность по-прежнему отображать одну и ту же таблицу, если хотите.

EDIT: Если вы получите дополнительные проблемы, отмените переименование. У меня возникли некоторые проблемы (больше ошибок и ошибок запросов), и после того, как я вернулся к ApplicationUser, эти проблемы исчезли, и проблема выше не повторилась -occur. Просто голова.

Ответ 3

Прочитайте указанные выше проблемы. Мой текст ошибки:

Несколько наборов объектов для каждого типа не поддерживаются. Наборы объектов "ApplicationUsers" и "Users" могут содержать экземпляры типа 'DataLayerIdentity.Models.ApplicationUser'

Я подозреваю, что ошибка была создана, когда я играл и строил модель: ApplicationUser в новом контроллере.

Решил его, удалив ниже: ApplicationDbContext.cs

    public System.Data.Entity.DbSet<DataLayerIdentity.Models.ApplicationUser> ApplicationUsers
    {
        get;
        set;
    }

Нет. Другие изменения, которые были сделаны для решения проблемы. Надеюсь, это поможет кому-то.

Ответ 4

Когда вы используете строительные леса для создания управления, vs автоматически вставляет 1 строку в контекст db

public System.Data.Entity.DbSet<...API.Models.ApplicationUser> ApplicationUsers { get; set; }

Просто удалите эту строку и в своем контроллере. изменение db.ApplicationUsers до db.Users

Ответ 5

Я потратил более одного дня на решение этой проблемы...: (((Класс переименования только обходной путь. Правильное решение - удалить эту строку из ApplicationContext (IdentityModels.cs). Я не знаю, когда она была вставлена ​​в мой код.

System.Data.Entity.DbSet ApplicationUsers {get; задавать; }

Пользователи управляются где-то внутри, должны быть ТОЛЬКО ОПРЕДЕЛЕННЫЕ ТАБЛИЦЫ ПОЛЬЗОВАТЕЛЯ. Это означает, что эта неправильная строка является вторым видом, и это является причиной появления сообщения об ошибке "Множественные объекты".

После удаления этой строки и компиляции я получил несколько сообщений об ошибках в моем автоматически создаваемом коде представления, поскольку он уже ссылался на неправильное объявление. Вы можете воссоздать представление или исправить код вручную, просто переименуйте неправильные ссылки на ApplicationUser, чтобы исправить пользователя (правильно определен где-то внутри, а не в IdentityModels.cs)

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

Теперь я полностью оправился от этой проблемы, и проблема с почти ROOT понятна. К сожалению, проблема с корнем, вероятно, является ошибкой в ​​VS2013, что создает неправильную дополнительную строку.

Но так или иначе, продолжайте улыбаться. Столкновение с такими ошибками ничто по сравнению с программированием на Java:)

Ответ 6

Вот простейшее решение. Когда вы добавляете/создаете вид (список) на основе ApplicationUser в качестве модели, VS2013 ADDS следующим образом в файл IdentityModels.vb или .cs.:

Приложения для использования в публичных ресурсах как System.Data.Entity.DbSet(из ApplicationUser)

Просто удалите это свойство, и проблема исчезнет.

Ответ 7

Если вы пытаетесь создать ApplicationUsersController, выполните следующие действия.

  • Удалите эту строку из IdentityModels.cs

    public System.Data.Entity.DbSet<Project.Models.ApplicationUser> ApplicationUsers { get; set; }
    
  • Создайте проект

    control + shift + b
    
  • Сгенерируйте контроллер

    Right click on the 'Controllers' folder.
    Add > Controller
    MVC Controller with views, using Entity Framework
    Model Class: ApplicationUser
    Add
    
  • Вернитесь к IdentityModels.cs и удалите эту строку. AGAIN

    public System.Data.Entity.DbSet<Project.Models.ApplicationUser> ApplicationUsers { get; set; }
    
  • Создайте проект

    control + shift + b
    
  • Измените вызовы базы данных с помощью ApplicationUsers на пользователей в ApplicationUsersController.cs

    control + f to bring up 'Find and Replace'
    Click 'Replace in files'
    Find what: db.ApplicationUsers
    Replace with: db.Users
    Replace All
    
  • Нажмите кнопку воспроизведения и перекрестите пальцы:)

Ответ 8

Что вы также можете сделать: Создайте пустой контроллер и добавьте код для DataContext самостоятельно

    protected ApplicationDbContext db { get; private set; }

    public HomeController() : this(new ApplicationDbContext())
    {
    }

    public HomeController(ApplicationDbContext db)
    {
        this.db = db;
    }

Затем создайте свои методы, такие как Index, Create и т.д., и создайте представления, щелкнув правой кнопкой мыши и "Добавить просмотр..." для каждого. Поднимите свои представления с помощью списка, создайте любой шаблон, который подходит, и выберите ApplicationUser в качестве модели.

Важно: удалите запись в "Класс контекста данных", или вы снова получите аналогичную ошибку. Но если вы оставите "контекстный класс данных" пустым, строительные леса будут работать нормально.

Ответ 9

Я исправил проблему, удалив DbSet из контекста, а затем изменив ссылки в контроллере от ApplicationUsers к пользователям. Это сработало - но теперь я не вижу смысла в использовании лесов. К большому количеству вещей нужно поддерживать на высшем уровне, и он просто не работает правильно. Теперь я знаю, что модели просмотра и репозиторий - это то, что я хочу.