代码优先 - 不需要字段是必需的

时间:2017-04-13 20:46:53

标签: c# entity-framework asp.net-core ef-code-first sql-server-2016

我有一个实体程序,它有两个外键到我的主题表(MainContactSubjectId,SecondaryContactSubjectId)。主要和次要都可以为空。出于某种原因,当我尝试插入实体程序时它出错(内部服务器错误)并且不会让我插入,除非存在Main和Secondary。下面是我的实体程序和我的一些dbContext。谁能看到我做错了什么?

    [Table("Program")]
    public class Program : Entity<long>
    {

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

        [Required]
        public long ProgramTypeId { get; set; }

        [Required]
        [MaxLength(4000)]
        public string ProgramName { get; set; }

        public long? MainContactSubjectId { get; set; }

        public long? SecondaryContactSubjectId { get; set; }

        public virtual ICollection<AppTables.Case_ProgramRequirements.Case_ProgramRequirement> Case_ProgramRequirement { get; set; }
        public virtual AppTables.ProgramTypes.ProgramType ProgramType { get; set; }
        public virtual AppTables.Subjects.Subject MainSubject { get; set; }
        public virtual AppTables.Subjects.Subject SecondarySubject { get; set; }
    }

我猜这个问题在这里,但我不确定它是什么。我最好的 猜是.HasRequired,但我不知道如何重写它。 如果没有此代码,则无法正确创建外键 和循环参考问题。 WillCascadeOnDelete(false)停止了 循环参考问题。

public virtual IDbSet<AppTables.Programs.Program> Programs { get; set; }


protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            modelBuilder.Entity<AppTables.Programs.Program>()
                    .HasRequired(m => m.MainSubject)
                    .WithMany(t => t.ProgramsMain)
                    .HasForeignKey(m => m.MainContactSubjectId)
                    .WillCascadeOnDelete(false);

            modelBuilder.Entity<AppTables.Programs.Program>()
                    .HasRequired(m => m.SecondarySubject)
                    .WithMany(t => t.ProgramsSecondary)
                    .HasForeignKey(m => m.SecondaryContactSubjectId)
                    .WillCascadeOnDelete(false);
    }

编辑1: 我相信我的问题在于数据访问层,但如果没有,我正在直接向我的应用服务层“创建”进行ajax调用。当我走过它时,一切看起来都很完美。它命中返回然后我得到内部服务器错误。没有其他细节。我尝试用try / catch包装,但是catch从未被击中过。

我使用的是Asp.net Boilerplate框架。我也在他们的私人论坛上发布但没有运气。我只是假设这是一个数据访问层问题,这就是我在这里发布的原因。

public async Task<> Create(ProgramInput model)
    {
            Program domainModel = new Program();
            domainModel.TenantId = (int)AbpSession.TenantId;
            domainModel.ProgramName = model.ProgramName;
            domainModel.ProgramTypeId = model.ProgramTypeId;
            domainModel.MainContactSubjectId = model.MainContactId;
            domainModel.SecondaryContactSubjectId = model.SecondaryContactId;
            domainModel.CreatedBy = (long)AbpSession.UserId.Value;
            domainModel.CreatedDate = Clock.Now;
            domainModel.IsDeleted = false;

            await _programRepository.InsertAsync(domainModel);

            return;
    }

编辑2: 这是我的主题表。它有50个列和10个外键,但我只会缩短相关数据。

public class Subject : Entity<long>
{
    public Subject()
    {
        this.ProgramsMain = new HashSet<AppTables.Programs.Program>();
        this.ProgramsSecondary = new HashSet<AppTables.Programs.Program>();
    }

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

    [Required]
    public long SubjectTypeId { get; set; }

    [MaxLength(1000)]
    public string FirstName { get; set; }

    [MaxLength(1000)]
    public string MiddleName { get; set; }

    [MaxLength(1000)]
    public string LastName { get; set; }

    [MaxLength(100)]
    public string Suffix { get; set; }

    [MaxLength(3000)]
    public string FullName { get; set; }
//A TON MORE COLUMNS ....




    public virtual AppTables.SubjectTypes.SubjectType SubjectType { get; set; }
    public virtual ICollection<AppTables.Programs.Program> ProgramsMain { get; set; }
    public virtual ICollection<AppTables.Programs.Program> ProgramsSecondary { get; set; }

ANSWER 我想出了我的答案。我切换.HasRequired .HasOptional,现在一切正常。抱歉浪费了每个人的时间。谢谢!

1 个答案:

答案 0 :(得分:0)

根据OP在他的问题中的回答编辑和评论:

根据以下代码将.HasRequired更改为.HasOptional。

public virtual IDbSet<AppTables.Programs.Program> Programs { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        modelBuilder.Entity<AppTables.Programs.Program>()
                .HasOptional(m => m.MainSubject)
                .WithMany(t => t.ProgramsMain)
                .HasForeignKey(m => m.MainContactSubjectId)
                .WillCascadeOnDelete(false);

        modelBuilder.Entity<AppTables.Programs.Program>()
                .HasOptional(m => m.SecondarySubject)
                .WithMany(t => t.ProgramsSecondary)
                .HasForeignKey(m => m.SecondaryContactSubjectId)
                .WillCascadeOnDelete(false);
}