我正在尝试使用EF Code First开发一个包含“在线朋友”功能的项目。我必须将所有用户的朋友存储在数据库中。我为用户提供“User”POCO课程,为朋友提供“FriendRelationship”POCO课程。这些POCO课程是:
[Table("UserTable")]
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
//other properties
public int? FriendListID {get; set;}
public virtual FriendRelationship FriendList { get; set; }
}
[Table("FriendRelationshipTable")]
public class FriendRelationship
{
public FriendRelationship()
{
Friends = new List<User>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public virtual List<User> Friends { get; set; }
}
我的Fluent API是:
modelBuilder.Entity<User>()
.HasOptional(o => o.FriendList)
.WithMany(m => m.Friends)
.HasForeignKey(fk => fk.FriendListID)
.WillCascadeOnDelete(false);
我正在User对象的第一次创建时在User对象中创建Friend对象(此User对象添加到控制器的数据库中):
public class CreateAccountModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
//other actions
User _user = new User();
_user.FriendList = new FriendRelationship();
//other actions and return
}
}
最后,我朋友的另外尝试:
static void AddFriendByManually()
{
using (var context = _liveCampusContext)
{
User Admin2 = context.Users.SingleOrDefault(w => w.Username == "Admin2");
User Admin = context.Users.SingleOrDefault(w => w.Username == "Admin");
User AdminVader= context.Users.SingleOrDefault(w => w.Username == "AdminVader");
Admin.FriendList.Friends.Add(Admin2);
Admin.FriendList.Friends.Add(AdminVader);
Admin2.FriendList.Friends.Add(Admin);
Admin2.FriendList.Friends.Add(AdminVader);
AdminVader.FriendList.Friends.Add(Admin2);
AdminVader.FriendList.Friends.Add(Admin);
context.SaveChanges();
}
}
当context.SaveChanges()行执行时,抛出异常:
违反了多重性约束。 “TeachLearnWeb.Data.DbContextFolder.User_FriendList”关系的“User_FriendList_Target”角色具有多重性1或0..1。
我错过了什么?感谢。
答案 0 :(得分:2)
根据您所显示的用法示例判断,这种关系实际上应该是多对多:
此外,朋友关系是双向的(我强烈怀疑)。
因此,在Admin.FriendList.Friends.Add(AdminVader);
之后,AdminVader的FriendList已经包含管理员,我们可以跳过第AdminVader.FriendList.Friends.Add(Admin);
行。
如果您想在关系本身上存储其他数据(例如,FriendSince时间戳),则只需要FriendRelationship
类。
否则将您的模型更改为
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
//other properties
public virtual ICollection<User> Friends { get; set; }
}
并按如下方式更改关系的配置:
ModelBuilder.Entity<User>()
.HasMany(u => u.Friends)
.WithMany()
.Map(m => m.ToTable("FriendRelationshipTable"));
答案 1 :(得分:1)
根据您的代码中给出的示例:
Admin.FriendList.Friends.Add(Admin2);
Admin.FriendList.Friends.Add(AdminVader);
*在上面的代码中,您要添加Admin2和AdminVader。
Admin2.FriendList.Friends.Add(Admin);
Admin2.FriendList.Friends.Add(AdminVader);
*在以上两行中,您要添加Admin和AdminVader。因此,AdminVader被添加两次导致Multiplicity约束。
您可能需要对表格进行更改。 在UserTable中,您可以存储所有用户。
[Table("UserTable")]
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name {get; set;}
}
在FriendRelationshipTable中,存储userID(将拥有一组朋友的用户)和FriendsUserId(这将存储用户拥有的朋友的id) [表( “FriendRelationshipTable”)] 公共类朋友关系 {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public ID
public int FriendUserID { get; set; }
public int UserID {get; set;}
}
我没有添加其他属性。 检查此表配置是否有效。