使用约定时如何使FK为必需?

时间:2018-10-21 10:20:38

标签: c# entity-framework

假设我有这样的实体。

public class Student
{
    public int StudentId { get; set; }
    public string StudentName { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }

    public ICollection<Student> Students { get; set; } 
}

实体框架将为我在Student表中生成FK,但是它将为空。我希望它是必需的,并且我也想使用此约定而不是其他约定。可能吗?如果不可能,您是否推荐其他技术?

1 个答案:

答案 0 :(得分:0)

查看以下示例

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int GradeId { get; set; }
    public Grade Grade { get; set; }
}

public class Grade
{

    public int GradeId { get; set; }
    public string GradeName { get; set; }

    public ICollection<Student> Student { get; set; }
}

在上面的示例中,Student实体包括外键属性GradeId及其参考属性Grade。这将与“学生”表中的“非空”外键列建立一对多关系,如下所示。 more here

完整的样本

 public partial class Product
{
    public int Id { get; set; }
    public int? UserId { get; set; }   // set nullable FK

    public User User { get; set; }
}
public partial class Ticket
{
    public int Id { get; set; }
    public int UserId { get; set; }  // set non nullable FK
    public string Title { get; set; }

    public User User { get; set; }
}
public partial class User
{
    public User()
    {
        Products = new HashSet<Product>();
        Tickets = new HashSet<Ticket>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<Product> Products { get; set; }
    public ICollection<Ticket> Tickets { get; set; }
}

 public partial class AngulartestContext : DbContext
{
    public AngulartestContext()
    {
    }

    public AngulartestContext(DbContextOptions<AngulartestContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Product> Products { get; set; }
    public virtual DbSet<Ticket> Tickets { get; set; }
    public virtual DbSet<User> Users { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
  #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
            optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=db;Persist Security Info=True;User ID=sa;Password=123456");
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>(entity =>
        {
            entity.Property(e => e.Id).ValueGeneratedNever();

            entity.HasOne(d => d.User)
                .WithMany(p => p.Products)
                .HasForeignKey(d => d.UserId)
                .HasConstraintName("FK_Products_Users");
        });

        modelBuilder.Entity<Ticket>(entity =>
        {
            entity.Property(e => e.Id).ValueGeneratedNever();

            entity.Property(e => e.Title).HasMaxLength(50);

            entity.HasOne(d => d.User)
                .WithMany(p => p.Tickets)
                .HasForeignKey(d => d.UserId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_Tickets_Users");
        });

        modelBuilder.Entity<User>(entity =>
        {
            entity.Property(e => e.Id).ValueGeneratedNever();

            entity.Property(e => e.Name).HasMaxLength(50);
        });

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}