实体框架中的复杂关系映射

时间:2011-10-11 15:34:57

标签: c# entity-framework-4

我正在建立一个预订系统。我有角色的用户('admin','client','employee','student')。

每个预订必须与角色客户的用户相关联,可能会分配给角色员工的用户,也可能会分配给角色学生的用户。

所以在我的预订类中,我有User类型的属性,我用[ForeignKey(“AnytypeId”)]属性标记它们,以提示关系的EF。

我在http://blog.stevensanderson.com/2011/01/28/mvcscaffolding-one-to-many-relationships/

看到过这样的代码
public class Reservation
{

    public int ReservationID
    {
        get;
        set;
    }

    [Required(ErrorMessage="Please provide a valid date")]
    public DateTime ReservationDate
    {
        get;
        set;
    }
    public DateTime ReservationEnd { get; set; }
    public DateTime EntryDate
    {
        get;
        set;
    }
    public DateTime UpdatedOn
    {
        get;
        set;
    }
    public decimal Ammount
    {
        get;
        set;
    }

    public decimal? Discount { get; set; }

    [DataType(DataType.MultilineText)]
    public string ServiceDetails { get; set; }

    [DataType(DataType.MultilineText)]        
    public string Remarks { get; set; }

    public string VoucherNumber { get; set; }

    public int ServiceID
    {
        get;
        set;
    }
    public Service Service
    {
        get;
        set;
    }

    public string EmployeeId { get; set; }
    [ForeignKey("EmployeeId")]
    public User Employee { get; set; }


    public string ClientId { get; set; }
    [ForeignKey("ClientId")]
    public User Client { get; set; }


    public string StudentId { get; set; }
    [ForeignKey("StudentId")]
    public User Student { get; set; }

}
public class User
{

    //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    //public Guid UserId { get; set; }

    [Key]
    [Required(ErrorMessage = "User Name is required")]
    [Display(Name = "User Name")]
    [MaxLength(100)]        
    public string UserName { get; set; }

    [Required]
    [MaxLength(64)]
    public byte[] PasswordHash { get; set; }

    [Required]
    [MaxLength(128)]
    public byte[] PasswordSalt { get; set; }

    [Required(ErrorMessage = "Email is required")]
    [DataType(DataType.EmailAddress)]
    [MaxLength(200)]
    public string Email { get; set; }

    [MaxLength(200)]
    public string Comment { get; set; }

    [Display(Name = "Approved?")]
    public bool IsApproved { get; set; }

    [Display(Name = "Crate Date")]
    public DateTime DateCreated { get; set; }

    [Display(Name = "Last Login Date")]
    public DateTime? DateLastLogin { get; set; }

    [Display(Name = "Last Activity Date")]
    public DateTime? DateLastActivity { get; set; }

    [Display(Name = "Last Password Change Date")]
    public DateTime DateLastPasswordChange { get; set; }

    public string address { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Phone { get; set; }

    public bool? IsActive { get; set; }

    public int? ClientTypeID { get; set; }
    public virtual ClientType ClientType { get; set; }

    public virtual ICollection<Role> Roles { get; set; }

    public DateTime? PackageValidity { get; set; }


    public virtual ICollection<Reservation> Reservations { get; set; }


}

public class UserMap : EntityTypeConfiguration<User>
{
    public UserMap()
    {
        this.HasMany(u => u.Roles)
         .WithMany(r => r.Users)
         .Map(m =>
         {
             m.ToTable("RoleMemberships");
             m.MapLeftKey("Username");
             m.MapRightKey("RoleName");
         });
    }
}

现在,当我运行我的mvc3 EF代码时,第一个为我创建的应用程序数据库,其中包含以下ERD和edmx模型。 enter image description here

现在我遇到的问题很少:  1.当我列出角色客户的所有用户时,即使他们在数据库中有预订,他们的预订属性也始终显示为0。  2.如果我试图删除在数据库中有预留的角色客户端用户,我会收到以下错误。

DELETE语句与REFERENCE约束“Reservation_Client”冲突。冲突发生在数据库“CRSDB”,表“dbo.Reservations”,列“ClientId”中。 声明已经终止。

我检查了ERD和edmx模型中的实际情况,他们没有应用级联删除。如何在删除角色客户端用户时指示EF删除所有预留,但不能删除角色员工或学生用户。

1 个答案:

答案 0 :(得分:1)

此代码可以解决问题

public class Reservation
{

    public int ReservationID
    {
        get;
        set;
    }

    [Required(ErrorMessage="Please provide a valid date")]
    public DateTime ReservationDate
    {
        get;
        set;
    }
    public DateTime ReservationEnd { get; set; }
    public DateTime EntryDate
    {
        get;
        set;
    }
    public DateTime UpdatedOn
    {
        get;
        set;
    }
    public decimal Ammount
    {
        get;
        set;
    }

    public decimal? Discount { get; set; }

    [DataType(DataType.MultilineText)]
    public string ServiceDetails { get; set; }

    [DataType(DataType.MultilineText)]        
    public string Remarks { get; set; }

    public String  PaymentMethod { get; set; }
    public string VoucherNumber { get; set; }

    public int ServiceID
    {
        get;
        set;
    }
    public virtual Service Service
    {
        get;
        set;
    }


    public string EmployeeID { get; set; }
    [ForeignKey("EmployeeID")]
    public virtual User Employee { get; set; }


    public string ClientID { get; set; }
    [ForeignKey("ClientID")]
    public virtual User Client { get; set; }


    public string StudentID { get; set; }
    [ForeignKey("StudentID")]
    public virtual User Student { get; set; }


}

public class ReservationMap : EntityTypeConfiguration<Reservation>
{
    public ReservationMap()
    {
        this.HasOptional(r => r.Client).WithMany().WillCascadeOnDelete(true);
        this.HasOptional(r => r.Employee).WithMany().WillCascadeOnDelete(false);
        this.HasOptional(r=>r.Student).WithMany().WillCascadeOnDelete(false);
    }
}