ASP .NET C#MVC 5代码优先外键属性/列名称

Dan7el

我是MVC的新手,并且在Visual Studio 2015中将MVC 5用于ASP .NET C#Web应用程序。

代码优先。

我的目标:在代码中定义外键关系,让脚手架在数据库中创建键。

我很难做到这一点。如果可能的话,我不希望使用Fluent API至少,我想了解1)为什么需要使用Fluent API,以及2)实际上如何使用它。

楷模

应用类型模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace MVCModelFirstSample.Models
{
    public class ApplicationType
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int ApplicationTypeID { get; set; }

        [Required]
        [MaxLength(50)]
        public string ApplicationTypeShortDescription { get; set; }

        [Required]
        [MaxLength(500)]
        public string ApplicationTypeLongDescription { get; set; }

        [Required]
        public int CreatedByUserID { get; set; }

        [Required]
        [DataType(DataType.Date)]
        public DateTime CreatedDate { get; set; }

        [Required]
        public int ModifiedByUserID { get; set; }

        [Required]
        [DataType(DataType.Date)]
        public DateTime ModifiedDate { get; set; }
    }
}

现在,我希望创建其他一些使用anApplicationTypeID作为外键的类。我创建了一个:

MVC5应用

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace MVCModelFirstSample.Models
{
    public class MVC5Application
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int MVC5ApplicationID { get; set; }

        [Required]
        public int ApplicationTypeID { get; set; }

        [Required]
        [MaxLength(500)]
        public string MVC5ApplicationDescription { get; set; }

        [Required]
        public int CreatedByUserID { get; set; }

        [Required]
        [DataType(DataType.Date)]
        public DateTime CreatedDate { get; set; }

        [Required]
        public int ModifiedByUserID { get; set; }

        [Required]
        [DataType(DataType.Date)]
        public DateTime ModifiedDate { get; set; }
    }
}

这些模型本身可以工作,并且我可以构建控制器,并且可以正确生成数据库,等等。但是,数据库的MVC5Application表中的ApplicationTypeID与ApplicationType表之间没有链接。

根据我的一些研究,有迹象表明可能会创建自动生成的外键关系,但目前尚不清楚。没有。

因此,我的第一个想法是[ForeignKey("ApplicationTypeID")]MVCApplication的属性定义上方添加一个属性

对我而言,这样做是有道理的(无论是否实际上明智,这是另一回事)。无论如何,摘要:

namespace MVCModelFirstSample.Models
{
    public class MVC5Application
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int MVC5ApplicationID { get; set; }

        [Required]
        [ForeignKey("ApplicationTypeID")]
        public int ApplicationTypeID { get; set; }

它会生成,当我尝试通过“创建控制器”操作添加新的MVCApplication时:

EntityFramework.dll中发生类型'System.InvalidOperationException'的异常,但未在用户代码中处理。其他信息:无法将属性'ApplicationTypeID'配置为导航属性。该属性必须是有效的实体类型,并且该属性应具有非抽象的getter和setter。对于集合属性,该类型必须实现ICollection,其中T是有效的实体类型。

这是我感到困惑的地方。我发誓,我已经搜寻,搜寻和搜寻。我在寻找不同的建议,但是我对如何设置它一无所知。

一种可能的选择是将类声明为键。我想,也许它会自动从类中检测ID并使用它?不确定,但是嘿,值得一试,对吗?似乎您可以在这些字符串值中放入所需的任何内容。除非有人使用它,否则没人会抱怨。

public class MVC5Application
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int MVC5ApplicationID { get; set; }

    [Required]
    [ForeignKey("ApplicationType")]
    public int ApplicationTypeID { get; set; }

错误:

EntityFramework.dll中发生类型'System.InvalidOperationException'的异常,但未在用户代码中处理。其他信息:类型'MVCModelFirstSample.Models.MVC5Application'的属性'ApplicationTypeID'上的ForeignKeyAttribute无效。在依赖类型“ MVCModelFirstSample.Models.MVC5Application”上找不到导航属性“ ApplicationType”。Name值应为有效的导航属性名称。

无论如何,那可能不是最好的主意。

通过定义类并提供外键,甚至可以通过代码优先生成外键关系吗?我试图在这里使事情尽可能简单。

理想情况下,我想使用键与数据库列名称不一定匹配。例如,我有一个User表,其UserID值与其他表中的CreatedByUserID相关。

话虽如此,我导致了Fluent API。

我有麻烦了 我需要查找和使用的DbContext到底在哪里?我想我终于明白了。

因为我使用了Internet身份验证,所以我具有IdentityModel.cs,其中包含以下内容:

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

...然后我将添加我的替代:

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

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }

在替代中,我将添加Fluent API。

根据使用Fluent API配置关系

重命名模型中未定义的外键

如果您选择不为CLR类型定义外键,但想指定它在数据库中应具有的名称,请执行以下操作:

modelBuilder.Entity<Course>() 
    .HasRequired(c => c.Department) 
    .WithMany(t => t.Courses) 
    .Map(m => m.MapKey("ChangedDepartmentID"));

否。我无法直接使用此代码。我要做的就是坐下来看看示例类,并将它们与我自己的类相关联。我意识到我对这些东西应该如何工作有些误解或理解。

我不得不像这样修改我的班级:

public class ApplicationType
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ApplicationTypeID { get; set; }

    [Required]
    [MaxLength(50)]
    public string ApplicationTypeShortDescription { get; set; }

    [Required]
    [MaxLength(500)]
    public string ApplicationTypeLongDescription { get; set; }

    [Required]
    public int CreatedByUserID { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime CreatedDate { get; set; }

    [Required]
    public int ModifiedByUserID { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime ModifiedDate { get; set; }

    public virtual ICollection<MVC5Application> Applications { get; set; }
}

public class MVC5Application
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int MVC5ApplicationID { get; set; }

    //[Required]
    //[ForeignKey("ApplicationType")]
    //public int ApplicationTypeID { get; set; }

    public virtual ApplicationType ApplicationType { get; set; }

    [Required]
    [MaxLength(500)]
    public string MVC5ApplicationDescription { get; set; }

    [Required]
    public int CreatedByUserID { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime CreatedDate { get; set; }

    [Required]
    public int ModifiedByUserID { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime ModifiedDate { get; set; }
}

现在,按照Fluent API文章中概述的模式进行操作:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<MVC5Application>()
        .HasRequired(r => r.ApplicationType)
        .WithMany(w => w.Applications)
        .Map(m => m.MapKey("ApplicationTypeID"));

    base.OnModelCreating(modelBuilder);
}

经过大量的迁移(代码优先迁移)后:

我认为我取得了理想的结果:

在此处输入图片说明

但是,我必须诚实。在这一点上,整个过程还很不直观。

有没有更好的办法?

另外,如果有人对使用代码优先创建数据库表有任何其他参考,以便使它更容易理解,我将不胜感激。

谢谢

斯凡

使用流畅的API,您可以使实体摆脱依赖于持久性的东西,并使模型保持在类库中,而无需依赖EF。我通常为DbContext创建一个第二项目,该项目包含配置,并且是唯一依赖于EF的项目。

如果声明导航属性(如最后使用ApplicationType属性所做的那样,EF会自动为您创建外键,这将使在对象模型中导航变得容易得多。Id用于数据库,在您的代码中要使用实类型的属性。

首先,您可以在EF Core文档中找到有关代码的更多信息

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ASP NET MVC剑道网格和列名称

来自分类Dev

在ASP.NET MVC 4中设置外键

来自分类Dev

ASP.NET MVC 5身份应用程序用户作为外键

来自分类Dev

如何在ASP.NET C#MVC中为现有软件创建SaaS应用程序

来自分类Dev

ASP.NET MVC 5 ApplicationUser作为外键

来自分类Dev

使用Asp.net Identity C#MVC登录和注册也需要添加我们自己的表

来自分类Dev

使用模型优先的ASP.NET MVC 5身份

来自分类Dev

asp.net 5与asp.net mvc是否不同?

来自分类Dev

Asp.net MVC路由名称,带“-”

来自分类Dev

为C#MVC ASP.NET应用程序创建的默认数据库在哪里?

来自分类Dev

ASP.NET MVC属性路由

来自分类Dev

ASP.NET 5和MVC的目的

来自分类Dev

使用实体框架的代码优先方法在ASP.NET MVC应用程序中缺少外键关系

来自分类Dev

ASP.NET MVC 6(ASP.NET Core或ASP.NET5)中的友好URL

来自分类Dev

C#MVC每周运行控制器代码

来自分类Dev

ASP NET MVC错误构造,使用外键插入

来自分类Dev

如何在Asp.net C#MVC中缓存数据库表以防止许多数据库查询

来自分类Dev

更改Asp.net MVC应用名称

来自分类Dev

在ASP.NET MVC 4中设置外键

来自分类Dev

Asp.Net MVC获取显示名称

来自分类Dev

C#MVC 4 ASP.net,如何将文件插入数据库存储中(二进制)

来自分类Dev

外键MVC 4代码优先C#

来自分类Dev

ASP.NET C#MVC剃刀视图中的堆叠柱形图

来自分类Dev

C#MVC确定成功的Http状态代码

来自分类Dev

C#MVC 5 HTML.ActionLInk

来自分类Dev

ASP.NET MVC读写设置属性

来自分类Dev

MVC 5代码优先编辑

来自分类Dev

ASP .NET - MVC 5 - 实体框架 - 代码优先 - 表单身份验证

来自分类Dev

插入外键asp.net mvc