【问题标题】:How to add a Foreign key in Customer table (CreatedBy column) for AspNetUser table (Id column) in ASP.NET MVC 5 Identity 2.0 using Code First如何使用 Code First 在 ASP.NET MVC 5 Identity 2.0 中为 AspNetUser 表(Id 列)在 Customer 表(CreatedBy 列)中添加外键
【发布时间】:2014-05-31 22:16:17
【问题描述】:

我使用 Visual Studio 2013 Update 2 RC 创建了 Empty MVC(ASP.NET Web 应用程序)项目 & 然后使用以下方法添加 AspNet 身份示例:

PM>安装包 Microsoft.AspNet.Identity.Samples -Pre

我已经启用并添加了迁移,然后更新了创建默认表的数据库。

我想创建包含 2 列作为外键的客户表:

  • 组表(GroupId 列)
  • AspNetUsers 表(Id 列)

所以我创建了 2 个类 Customer 和 Group 并使用 Data-annotations 添加了外键,如下所示:

namespace IdentitySample.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        static ApplicationDbContext()
        {
            // Set the database intializer which is run once during application start
            // This seeds the database with admin user credentials and admin role
            Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Group> Groups { get; set; }
    }

    public class Customer
    {
        public int CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public int GroupId { get; set; }
        public string CreatedBy { get; set; }



        [ForeignKey("GroupId")]
        public Group Groups { get; set; }

        [ForeignKey("CreatedBy")]
        public ApplicationUser ApplicationUsers { get; set; }
    }

    public class Group
    {
        public int GroupId { get; set; }
        public string GroupName { get; set; }
    }
}

一切看起来都很好,使用 EF Power 工具创建的 ApplicationDbContext.edmx 图表看起来也很好,并且项目构建正确。

然后我使用“MVC 5 Controller with views, using Entity Framework”脚手架模板添加了 CustomersController。

现在我收到编译错误(在 db.ApplicationUsers)

// GET: Customers/Create
public ActionResult Create()
{
    ViewBag.CreatedBy = new SelectList(db.ApplicationUsers, "Id", "Email");
    ViewBag.GroupId = new SelectList(db.Groups, "GroupId", "GroupName");
    return View();
}

错误详情: “IdentitySample.Models.ApplicationDbContext”不包含“ApplicationUsers”的定义,并且找不到接受“IdentitySample.Models.ApplicationDbContext”类型的第一个参数的扩展方法“ApplicationUsers”(您是否缺少 using 指令或程序集参考?)

当我在ApplicationDbContext中添加以下代码时

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

我得到错误:

不支持每种类型的多个对象集。对象集 'ApplicationUsers' 和 'Users' 都可以包含类型的实例 'IdentitySample.Models.ApplicationUser'

我想将 CreatedBy 作为外键添加到 AspNetUsers,模板使用它生成类似于 GroupId 下拉列表的 CreatedBy 下拉列表:

我们如何将身份生成的表与其他用户创建的表一起使用,其中用户创建的表具有对身份生成表的外键引用。并且拥有使用“MVC 5 Controller with views, using Entity Framework”的一流脚手架代码生成经验?
(类似于我们的客户和组表,其中客户表具​​有 GroupId 外键参考)

【问题讨论】:

    标签: c# asp.net entity-framework foreign-keys asp.net-identity


    【解决方案1】:

    RTFE:您的 ApplicationDbContext 类上没有 ApplicationUsers 属性。

    只需添加:

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

    【讨论】:

    • 我也试过添加这个,但在运行时出现错误:Multiple object sets per type are not supported. The object sets 'ApplicationUsers' and 'Users' can both contain instances of type 'IdentitySample.Models.ApplicationUser'.
    • 啊,那样的话,你需要使用ViewBag.CreatedBy = new SelectList(db.Users, "Id", "Email");来检索用户。
    • 非常感谢,它有效。但是,有没有什么方法可以让CustomersController脚手架模板代码默认添加db.Users而不是我们手动更改db.ApplicationUsers
    • Rudi,ApplicationUsers 它不应该在那里,它已经在 ASP.NET Identity 下使用 DBContext...
    • 这是一个正确的答案吗?为什么要标记这个...我认为这是错误的。就像@dima 说的那样
    【解决方案2】:

    Entity Framework 足够智能,可以识别 ID/键的常规名称。因此,为了添加外键,您可以这样做:

    public class Customer
    {
        public string CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    
        public int ApplicationUserId { get; set; }
        public virtual ApplicationUser ApplicationUser { get; set; } 
    }
    

    按照惯例,它匹配一个类名加上“Id”作为外键。如果您不想使用此约定,则可以使用 ForeignKey 数据注释来帮助 EF 了解应该是什么外键:

    public class Customer
    {
        public string CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    
        public int UserId { get; set; }
        [ForeignKey("UserId")]
        public ApplicationUser ApplicationUser { get; set; }
    }
    

    查看thisthis 文章了解更多信息。

    【讨论】:

    • 我已尝试按上述方式添加 UserId,但仍然出现错误。我添加了图像和组类来更详细地解释我的问题。
    • 等等,但问题是关于添加外键的正确方法,现在你修改了问题?这不是它应该如何工作的。你应该关闭你原来的 Q 并问另一个。现在您想做与您最初提出的完全不同的事情,而我的回答与那些真正寻找添加外键的正确方法的人无关。
    • 关于你的新问题,到处都是,你试图一次做多件事并提出多个问题......你需要专注于一件事,然后移动到另一个...您尝试在Customer 类中定义ApplicationUsersGroups 的方式是一对一的关系,但是您想为它们创建一个下拉列表...其次,当您重新搭建Customer 对象,然后由于某种原因你想为ApplicationUser 创建一个下拉列表,我并没有真正得到你想要通过这样做来完成什么,第三,CreatedBy 是一个字符串
    • 借助您提供的信息和链接以及 Rudi 评论,我能够在客户表中创建外键并在默认模板创建的下拉列表中填充 UserId。
    • 这个答案实际上为我解决了一个非常相似的问题。试图将 ApplicationUser 添加为外键,但它不起作用。添加了 [ForeignKey()] 属性以指向我想要使用的实际外键并立即使用!工作。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多