【问题标题】:Entity Framework Modeling code first实体框架建模代码先
【发布时间】:2017-01-27 05:28:03
【问题描述】:

我有一个我认为是简单的建模问题,但由于某种原因,我无法弄清楚解决它的最佳方法是什么。

我有一个 Person 类(包含有关用户的信息),我有一个 PhoneCarrier 类,其中包含有关 PhoneCarriers 的信息(他们的姓名和用于向个人电话发送电子邮件的电子邮件扩展名)。

这是 Person 类

 public class Person
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Display(Name = "First Name")]
    [Required(ErrorMessage ="{0} is required")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    [Required(ErrorMessage ="{0} is required")]
    public string LastName { get; set; }

    [Display(Name = "Dish Order")]
    //[Range(1, byte.MaxValue, ErrorMessage = "Value of {0} must be greater than 0")]
    public  byte DishOrder { get; set; }

    [Display(Name = "E-Mail")]
    [RegularExpression(".+\\@.+\\..+",
    ErrorMessage = "Please enter a valid email address")]
    public string Email { get; set; }

    [DataType(DataType.Text)]
    [RegularExpression(@"(^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$)", ErrorMessage = "{0} must be a numeric value of length 10")]
    [Display(Name = "Phone Number")]
    //[DisplayFormat(DataFormatString = "{0:###-###-####")]
    public string PhoneNumber { get; set; }

    [Display(Name = "Phone Carrier")]
    public int PhoneCarrier { get; set; }

    public virtual ICollection<Fine> Fines { get; set; }

    public virtual ICollection<DishDate> DishDates { get; set; }

    [NotMapped]
    public static IEnumerable<PhoneCarrier> PhoneCarriers { get; set; }

这是 PhoneCarrier 类

public class PhoneCarrier
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required(ErrorMessage ="{0} is required")]
    public string Company { get; set; }

    [Display(Name = "Email Extension")]
    [Required(ErrorMessage ="{0} is required")]
    public string EmailExtension { get; set; }
}

我想知道这是否是建模的正确方法,我觉得他们似乎是一个更好的解决方案,因为现在,如果我想获取有关某个人的电话运营商的信息,我必须首先获得该人的phonecarrier id,然后我必须调用 id = phonecarrier id 的 PhoneCarrier。这是一个实际的例子

var phoneCarrierId = person.PhoneCarrier;
            return db.PhoneCarriers.Where(x => x.ID == phoneCarrierId).FirstOrDefault().EmailExtension;

有没有一种方法可以将其设置为可以调用 db.Person.PhoneCarrier.EmailExtension 的位置(例如在 PhoneCarrier 类型的 Person 类中创建 int PhoneCarrier 字段)?这似乎是一种更清洁的方法,我想知道这是否可能,或者我这样做的方式是否更正确......

【问题讨论】:

  • 为什么你有 IEnumerable PhoneCarrier in Person。是否存在一对多关系?

标签: c# entity-framework database-design entity-framework-6 c#-5.0


【解决方案1】:

下面的代码将解决这个问题。我建议将类中的 id 属性更改为 TableNameId,例如 PersonId 和 PhoneCarrierId。

查看这里了解更多信息 - https://msdn.microsoft.com/en-us/data/jj713564.aspx

public class Person
{
    public int PersonId {get;set;}
    //...
    public int PhoneCarrierId { get; set; }
    public virtual PhoneCarrier PhoneCarrier { get; set; }
}

public class PhoneCarrier 
{
    public int PhoneCarrierId {get;set;}
    //...
}

【讨论】:

  • 您刚刚删除了您的答案并创建了一个具有相同详细信息的新答案,您知道拥有 10k 代表或更多的人仍然可以看到已删除的帖子吗?
  • 我不明白是什么问题,我已经把答案说的更清楚了,你不能别管它吗?
  • 如果您删除一个答案并使用相同的信息创建另一个答案,这是不好的行为。我只是想在这里帮助你。
  • 谢谢,以后我会记住的。希望你有一个美好的一天。
【解决方案2】:

使用导航属性。请参阅此处的示例:Code First Conventions。看看示例中的部门与课程的关系。

【讨论】:

    【解决方案3】:

    您只需为该人分配一个电话运营商,而不是整个列表。另外,重命名 ID 字段:

    public class Person
    {
        //snip
    
        public int PhoneCarrierId { get; set; }
        public virtual PhoneCarrier PhoneCarrier { get; set; }
    }
    

    现在当你得到你的人时,你可以简单地做到:

    var person = db.Persons.Where(p => p.ID == 1);
    var carrier = person.PhoneCarrier;
    

    注意:如果你没有使用延迟加载,那么你可能需要Include运营商:

    var person = db.Persons.Include(p => p.PhoneCarrier).Where(p => p.ID == 1);
    

    【讨论】:

      猜你喜欢
      • 2021-09-01
      • 2020-04-10
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多