1

我在使用 EF 5 Code First 时遇到了一些问题,主要是因为我不知道我必须寻找什么行为。

这是关于编写日历后端。

日历包括 CalendarEntries 列表 日历由用户拥有 CalendarEntry 有所有者(与日历相同)

问题是:当我将用户添加到日历条目时它可以工作,但是当我想将同一用户添加到另一个条目时,第一个日历条目会失去用户(CalendarEnty.Invitees)

另一方面,正确列出了用户的邀请数量,并且邀请表也具有正确的值。

有关如何解决此问题的任何提示?

    public class Calendar
{
    [Key]
    public int CalendarId { get; set; }

    [Required]
    public virtual User Owner { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public virtual ICollection<CalendarEntry> CalendarEntries { get; set; }
    }

 public class CalendarEntry
{
    public CalendarEntry()
    {
        Invitees = new List<User>();
    }
    public virtual ICollection<User> Invitees { get; set; }


    public bool IsEmpty
    {
        get
        {
            if (Invitees.Count == 0)
            {
                return true;
            }
            return false;
        }
    }


    [Key]
    public int CalendarEntryId { get; set; }
    [Required]
    public DateTime StartDate { get; set; }
    [Required]
    public DateTime EndDate { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public double Duration
    {
        get
        {
            return EndDate.Subtract(StartDate).TotalMinutes;
        }
    }

    public int OwnerId { get; set; }
    public virtual User Owner { get; set; }
    public int CalendarId { get; set; }
    public virtual Calendar Calendar { get; set; }
    public virtual Room Room { get; set; }
}

   public class Invite
{

   [Key]
   public int InviteId { get; set; }
   public virtual CalendarEntry CalendarEntry { get; set; }
   public int Accepted { get; set; }
   public virtual User Owner {get; set;}

}

    public class User
{
    [Key]

    public int UserId { get; set; }
    [Required]       
    public string GivenName { get; set; }
    [Required]    
    public string Surname { get; set; }
    [Required]       
    public string MailAddress { get; set; }
    public string PhoneNumber { get; set; }

    public virtual Calendar Calendar { get; set; }
    public int? CalendarId { get; set; }

    //SHA512Hashed

    private string _password = null;
    public string Password
    {
        get
        {
            return _password;
        }
        set
        {
            _password = value;
        }
    }

    public virtual ICollection<Group> Groups { get; set; }
    public virtual ICollection<Invite> Invites { get; set; }
}

用户和邀请的 ID 用于从 WCF 服务更轻松地访问项目这就是我不使用组合键的原因

通过以下方法,我确保只添加一次用户,我怀疑这会造成一些麻烦吗?不幸的是,我真的不知道如何解决它。

        public int AddUser(User dbUser)
    {
        var users = this.GetAllUser();

        if (users != null && users.Where(p => p.MailAddress == dbUser.MailAddress).Count() > 0)
        {
            return 0;
        }

        try
        {
            _calendarDatabase.User.Add(dbUser);
            _calendarDatabase.SaveChanges();
            return dbUser.UserId;
        }
        catch (Exception ex)
        {
            _logger.Error(ex.ToString());
        }
        return 0;
    }
4

1 回答 1

1

您没有显示您的 User 模型,但我怀疑您没有在其中声明对 CalendarEntry 模型(集合)的引用。确保您已将其声明为:

public class User
{
  public ICollection<CalendarEntry> CalendarEntries { get; set; }
  // ... other User properties
}

如果省略此引用,则 EF 将假定 CalendarEntry 和 User 之间的关系是多对一的,这意味着任何给定的 User 只能与单个 CalendarEntry 关联(尽管每个 CalendarEntry 可能有多个用户)。因此,当您将用户分配给 CalendarEntry 时,它将从任何先前的关系中删除。

通过将导航属性(作为集合)放入User模型中,您告诉 EF 实际上这种关系是多对多的,在这种情况下,它将在幕后为您生成一个映射表,以允许用户与任意数量的 CalendarEntries 相关联。

编辑-

当您在 EF 中具有多对多关系时,您可以为该关系显式指定映射表,或者只让 EF 根据您在对象中定义的导航属性为您生成表。通过在引用另一个对象的每个对象中放置一个集合属性,EF 可以推断出多对多关系并采取相应的行动。

当您有关系的其他信息时,例如指示您的代码中是否User已接受Invitea的位CalendarEntry,您需要明确指定映射表。执行此操作时,在 EF 中对其进行编码的最简单方法是让关系的每一方都有一个导航属性,该属性是对映射对象集合的引用,而不是关系中的其他对象。

所以,在你的情况下,这一行在CalendarEntry

public virtual ICollection<User> Invitees { get; set; }

应该是:

public virtual ICollection<Invite> Invitations { get; set; }

获得您期望的行为(例如,User通过 Invite 映射对象让 a 与多个 CalendarEntry 对象相关联)。

于 2013-06-18T02:22:39.180 回答