【问题标题】:Inner Joining Tables with 2 different variables具有 2 个不同变量的内部连接表
【发布时间】:2016-04-08 14:25:28
【问题描述】:

这是一个带有 EF6 Identity Web 应用程序的 MVC5

您可以从我的 cshtml 页面看到的管理员列是 IssuedTo。 Issueto 链接到我的 AspNetUsers 中的 id。

我正在尝试显示 IssueTo 指向的名称,所以如果它是 1,它应该显示 Andy Domagas 而不是 1。

我尝试通过为 IssuedTo 而不是 User 创建一个虚拟 ApplicationUser 属性来为 User 做我所做的事情。我通过添加 [ForeignKey("IssuedTo")] public virtual ApplicationUser assignedAdmin{ get; set; } 然后在我的视图中使用 @Html.DisplayFor(modelItem => item.IssuedUser.LastName) 来做到这一点,但我得到 引入 FOREIGN KEY 约束可能会导致循环或多个级联路径

IdentityModel.cs(ApplicationUser)(添加了TicketIssuedTo Collection)

namespace RecreationalServicesTicketingSystem.Models
{
    public class ApplicationUserLogin : IdentityUserLogin<int> { }
    public class ApplicationUserClaim : IdentityUserClaim<int> { }
    public class ApplicationUserRole : IdentityUserRole<int> { }

    public class ApplicationRole : IdentityRole<int, ApplicationUserRole>, IRole<int>
    {
        public string Description { get; set; }

        public ApplicationRole() : base() { }
        public ApplicationRole(string name)
            : this()
        {
            this.Name = name;
        }

        public ApplicationRole(string name, string description)
            : this(name)
        {
            this.Description = description;
        }
    }

    public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>, IUser<int>
    {
        public async Task<ClaimsIdentity>
            GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
        {
            var userIdentity = await manager
                .CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            return userIdentity;
        }

        public bool IsAdministrator { get; set; }
        [StringLength(50, MinimumLength = 1)]

        public string LastName { get; set; }
        [StringLength(50, MinimumLength = 1, ErrorMessage = "First name cannot be longer than 50 characters.")]

        [Column("FirstName")]
        public string FirstMidName { get; set; }

        public string FullName
        {
            get { return FirstMidName + " " + LastName; }
        }
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime EnrollmentDate { get; set; }
        public int DepartmentID { get; set; }
        [ForeignKey("DepartmentID")]
        public virtual Department Department { get; set; }
        public int DepotID { get; set; }
        [ForeignKey("DepotID")]
        public virtual Depot Depot { get; set; }
        public virtual ICollection<Ticket> Tickets { get; set; }

        public virtual ICollection<ApplicationUser> TicketsIssuedTo { get; set; }




    }


    public class ApplicationDbContext
        : IdentityDbContext<ApplicationUser, ApplicationRole, int,
        ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

            modelBuilder.Entity<Ticket>()
            .HasRequired(t => t.IssuedUser)
            .WithMany(u => u.TicketsIssuedTo)
            .HasForeignKey(t => t.IssueID)
            .WillCascadeOnDelete(false);
        }
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }

        static ApplicationDbContext()
        {
            Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
        }


        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }


        public DbSet<Ticket> Tickets { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Department> Departments { get; set; }
        public DbSet<Depot> Depots { get; set; }


    }



    public class ApplicationUserStore :
    UserStore<ApplicationUser, ApplicationRole, int,
    ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>, IUserStore<ApplicationUser, int>, IDisposable
    {
        public ApplicationUserStore()
            : this(new IdentityDbContext())
        {
            base.DisposeContext = true;
        }

        public ApplicationUserStore(DbContext context)
            : base(context)
        {
        }
    }


    public class ApplicationRoleStore
    : RoleStore<ApplicationRole, int, ApplicationUserRole>,
    IQueryableRoleStore<ApplicationRole, int>,
    IRoleStore<ApplicationRole, int>, IDisposable
    {
        public ApplicationRoleStore()
            : base(new IdentityDbContext())
        {
            base.DisposeContext = true;
        }

        public ApplicationRoleStore(DbContext context)
            : base(context)
        {
        }
    }

}

Ticket.cs(添加了 IssuedID 和 IssuedUser )

public class Ticket
{
    public int? TicketID { get; set; }
    [Required(ErrorMessage = "Please enter the description")]
    public string Issue { get; set; }
    [Display(Name = "Administrator")]
    [Required(ErrorMessage = "Please select the Administrator")]
    public int IssuedTo { get; set; }
    public int Author { get; set; }

    [DisplayFormat(NullDisplayText = "No Priority")]
    public Priority Priority { get; set; }
    [Required]
    [ForeignKey("CategoryID")]
    public virtual Category Category { get; set; }
    public int CategoryID { get; set; }

    public int UserID { get; set; }  
    [ForeignKey("UserID")]
    public virtual ApplicationUser User { get; set; }

    public int IssueID { get; set; }
    [ForeignKey("IssueID")]
    public virtual ApplicationUser IssuedUser { get; set; }

}

解决这个问题让我很头疼,所以我的问题是还有其他选择吗?

我可以在 TicketController Index 方法中使用 Linq 语句吗? SELECT FirstName LastName etc. INNER JOIN User Table.id with Ticket Table.Administrator(IssuedTo) ??

在 Gert 建议使用 FluentAPI 后更新代码 IdentityModel.cs(在 OnModelCreating 方法内部)

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Ticket>()
    .HasRequired(t => t.IssuedUser)
    .WithMany(u => u.TicketsIssuedTo)
    .HasForeignKey(t => t.IssueID)
    .WillCascadeOnDelete(false);
 }

你的错误

无法将 lambda 表达式转换为预期的委托类型,因为 块中的某些返回类型不可隐式转换 到委托返回类型 RecreationalServicesTicketingSystem

TicketIssuedTo 出错

无法隐式转换类型 System.Collections.Generic.ICollection RecreationalServicesTicketingSystem.Models.ApplicationUser 到 System.Collections.Generic.ICollection RecreationalServicesTicketingSystem.Models.Ticket。存在显式转换(您是否缺少演员表?)

【问题讨论】:

    标签: c# entity-framework linq


    【解决方案1】:

    你只能通过流畅的映射来解决这个问题,因为你需要从一个外键中删除级联删除:

    modelBuilder.Entity<Ticket>()
                .HasRequired(t => t.IssuedUser)
                .WithMany(u => u.TicketsIssuedTo)
                .HasForeignKey(t => t.IssueID)
                .WillCascadeOnDelete(false);
    

    这是在 DbContext 子类的 OnModelCreating 覆盖中。

    但是你有...

    public virtual ICollection<ApplicationUser> TicketsIssuedTo { get; set; }
    

    ...应该是:

    public virtual ICollection<Ticket> TicketsIssuedTo { get; set; }
    

    【讨论】:

    • 在我的`public class ApplicationDbContext`里面我有base.OnModelCreating(modelBuilder);modelBuilder.Conventions.Remove&lt;OneToManyCascadeDeleteConvention&gt;();(因为我试图删除级联删除)我也应该删除它们吗?
    • 我不会删除该约定。级联删除可以带来巨大的性能提升。我只会在不需要的地方删除级联删除。
    • 我认为您不需要在 `modelBuilder.Entity() 末尾添加 . 我也遇到了一些错误,我已经在我的问题中更新了它。
    • 现在我完全不清楚你做了什么。你的 current Ticket 类是什么样的?您显示它两次,都具有不同的附加属性。哪个 FK 导致了异常?
    • 抱歉!我一直在尝试自己修复它并更改了一些代码。我已经更新了问题中的代码!我相信这是`外键约束'FK_dbo.Tickets_dbo.AspNetUsers_UserID'`
    猜你喜欢
    • 2013-04-19
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 2021-09-12
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多