我需要在两个代码优先实体之间创建一个复杂的关系,但是我很难将我的大脑包裹起来

时间:2013-04-17 00:35:52

标签: c# .net entity-framework ef-code-first entity-framework-5

我有两个实体,这两个实体之间有两种不同的关系。第一种关系是一对多关系,第二种关系是多对多关系。请参阅以下实体。

public class User
{
    public int Id { get; set; }
    public string Password { get; set; }
    public string Name { get; set; }

    // Collection that represent this user's attached social providers.
    public virtual ICollection<SocialProvider> SocialProviders { get; set; }
    // Collection representing this user's friends from her attached social providers.
    public virtual ICollection<SocialProvider> SocialContacts { get; set; }
}

public enum Provider
{
    Google,
    Facebook,
    Twitter
}

public class SocialProvider
{
    public int Id { get; set; }
    public Provider Provider { get; set; }
    // Granted access token for talking to the provider API on user's behalf.
    public string AccessToken { get; set; }
    // User's unique ID at the social provider.
    public string ProviderId { get; set; }

    // The user that this SocialProvider belongs to.
    public virtual User User { get; set; }
    // The users that have this social provider as a contact.
    public virtual ICollection<User> Contacts { get; set; }
}

工作流程如下:

  1. 我在申请表中注册。这会创建User
  2. 我附上社交提供商(Google,Facebook等)。这会创建一个或多个SocialProvider并将其添加到user.SocialProviders
  3. 我从我附加的社交提供商处导入我的联系人/朋友。这会下拉社交联系人列表,并为每个联系人创建SocialProvider(如果尚不存在),并将其添加到user.SocialContacts。在这种情况下,SocialProvider将没有“拥有”它的父用户,也不会有AccessToken,直到用户注册应用程序并添加与其匹配的社交提供商,其中如果将填充这些东西。
  4. 这会有用吗?我有一种感觉EF即将变得非常困惑。我不熟悉流畅的API甚至大多数数据注释。关于我可以做些什么来做这项工作的任何建议,或者我应该让SocialContacts成为一个名为SocialContact的新实体,大多看起来像SocialProvider只是为了避免任何令人困惑的关系?< / p>

1 个答案:

答案 0 :(得分:1)

试试这个:

用户

public class User
{
   public int Id { get; set; }
   ublic string Password { get; set; }
   public string Name { get; set; }

   // Collection that represent this user's attached social providers.
   public virtual ICollection<SocialProvider> SocialProviders { get; set; }

   // Collection representing this user's friends from her attached social providers.
   public virtual ICollection<SocialProvider> SocialContacts { get; set; }
}

<强> SocialProvider

public class SocialProvider
{
   public int Id { get; set; }        

   public string AccessToken { get; set; }       

   [ForeignKey("Provider"), DatabaseGenerated(DatabaseGeneratedOption.None)]
   public string ProviderId { get; set; }

   public Provider Provider { get; set; }

   [ForeignKey("User"), DatabaseGenerated(DatabaseGeneratedOption.None)]
   public string UserId { get; set; }

   // The user that this SocialProvider belongs to.
   public virtual User User { get; set; }

   // The users that have this social provider as a contact.
   public virtual ICollection<User> Contacts { get; set; }
}

然后在你的DbContext类

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
          .HasMany<SocialProvider>(r => r.SocialContacts)
          .WithMany(u => u.Contacts)
          .Map(m =>
          {
              m.ToTable("UsersInSocialContacts");
              m.MapLeftKey("UserId");
              m.MapRightKey("ProviderId");//If not ProviderId  try Id
          });
    }

我不能也不测试这个,所以让我知道结果,这样我就可以改进它。理想情况下,您可能需要分开选择此设计并将其重组为一个或多个实体。