Inv*_*Dev 17 entity-framework self-join self-reference ef-code-first entity-framework-4.1
我有一个用户可以收集他喜欢的用户...
另一个用户可以收集他喜欢的用户....
如果用户A喜欢用户B,并且用户B喜欢用户A,那么他们就会挂出.我需要向对方发送他们的联系信息.我们如何在Entity Framework Code First中代表这样的模型?
public class User
{
public int UserId { get; set; }
public int? UserLikeId { get; set; }
public virtual UserLike UserLike { get; set; }
}
public class UserLike
{
public int UserLikeId { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public virtual ICollection<User> LikeUsers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这个型号是否正确?我不能让这个工作.
我尝试过另一种方式,但这也不行...
我试图将用户集合添加到用户表.
例如:
public virtual ICollection<User> userlike { get; set; }
public class User
{
public int UserId { get; set; }
public virtual ICollection<UserLike> UserLikes { get; set; }
}
public class UserLike
{
public int UserLikeId { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public int LikeUserId { get; set; }
public virtual User LikeUser { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我尝试添加用户和他们喜欢的人时,我收到此错误:
已检测到与"UserLike_LikeUser"关系的"UserLike_LikeUser_Target"角色发生冲突的更改.
代表这种模型的最佳方式是什么?
Mor*_*avi 23
你真的不需要一个单独的实体来描述这种关系,下面的对象模型可以解决这个问题:
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public int? ThisUserLikesId { get; set; }
public virtual User ThisUserLikes { get; set; }
public virtual ICollection<User> LikeThisUser { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOptional(u => u.ThisUserLikes)
.WithMany(u => u.LikeThisUser)
.HasForeignKey(u => u.ThisUserLikesId);
}
}
Run Code Online (Sandbox Code Playgroud)
现在假设您手中有一个UserId,并希望找到喜欢此用户的其他用户,该用户也喜欢他:
using (var context = new Context())
{
// For a given user id = 1
var friends = (from u in context.Users
where u.UserId == 1
from v in u.LikeThisUser
where v.UserId == u.ThisUserLikesId
select new
{
OurUser = u,
HerFriend = v
})
.SingleOrDefault();
ExchangeContactInfo(friends.OurUser, friends.HerFriend);
}
Run Code Online (Sandbox Code Playgroud)
自引用多对多关联将使用连接表映射到数据库,该连接表需要不同的对象模型和完全流畅的API:
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public virtual ICollection<User> ThisUserLikes { get; set; }
public virtual ICollection<User> UsersLikeThisUser { get; set; }
}
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(u => u.ThisUserLikes)
.WithMany(u => u.UsersLikeThisUser)
.Map(c =>
{
c.MapLeftKey("UserId");
c.MapRightKey("OtherUserId");
c.ToTable("UserLikes");
});
}
}
Run Code Online (Sandbox Code Playgroud)
正如我在这篇文章中解释的那样,多对多关联不能有有效载荷(例如EventId),如果是这种情况,那么我们必须将它分解为两个一对多关联到一个介入类,我可以看你已经正确地创建了这个类(UserLike)来表示附加到你自引用多对多关联的额外信息,但是这个中间类的关联不正确,因为我们需要准确定义2多对一从UserLike到User的关联,就像我在以下对象模型中展示的那样:
public class User
{
public int UserId { get; set; }
public string Email { get; set; }
public virtual ICollection ThisUserLikes { get; set; }
public virtual ICollection UsersLikeThisUser { get; set; }
}
public class UserLike
{
public int UserLikeId { get; set; }
public int LikerId { get; set; }
public int LikeeId { get; set; }
public int EventId { get; set; }
public User Liker { get; set; }
public User Likee { get; set; }
public virtual Event Event { get; set; }
}
public class Event
{
public int EventId { get; set; }
public string Name { get; set; }
}
public class Context : DbContext
{
public DbSet Users { get; set; }
public DbSet Events { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasMany(u => u.ThisUserLikes)
.WithRequired(ul => ul.Liker)
.HasForeignKey(ul => ul.LikerId);
modelBuilder.Entity()
.HasMany(u => u.UsersLikeThisUser)
.WithRequired(ul => ul.Likee)
.HasForeignKey(ul => ul.LikeeId)
.WillCascadeOnDelete(false);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用以下LINQ查询来检索彼此喜欢的所有用户:
using (var context = new Context())
{
var friends = (from u1 in context.Users
from likers in u1.UsersLikeThisUser
from u2 in u1.ThisUserLikes
where u2.LikeeId == likers.LikerId
select new
{
OurUser = u1.UserId,
HerFriend = u2.LikeeId
})
.ToList();
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.