我Payments
之间Users
。 Payment
有一个FromUser
和一个ToUser
。我用以下方法测试了实体关系:
var newPayment = new Payment() {
FromUserId = user1.UserId,
ToUserId = user2.UserId
};
db.Payments.Add(newPayment);
db.SaveChanges();
var tempPaymentId = user1.Payments.First().PaymentId;
newPayment = db.Payments.First(s => s.PaymentId == tempPaymentId);
Assert.AreEqual(newPayment.FromUserId, user1.UserId); // true
Assert.AreEqual(newPayment.ToUserId, user2.UserId); // true
Assert.AreEqual(user1.Payments.Count(), 1); // true
Assert.AreEqual(user2.Payments.Count(), 1); // false
我的问题是 - 为什么user2
没有Payments
?
分类和流畅的配置:
public class Payment {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PaymentId { get; set; }
[ForeignKey("FromUser")]
public int FromUserId { get; set; }
public User FromUser { get; set; }
[ForeignKey("ToUser")]
public int ToUserId { get; set; }
public User ToUser { get; set; }
}
public PaymentConfiguration() {
HasRequired(s => s.FromUser);
HasRequired(s => s.ToUser);
}
public UserConfiguration() {
// One-to-Many
HasMany(s => s.Payments);
}
答案 0 :(得分:0)
这可能是由于许多原因,但首先,您混合了数据注释和 Fluent API 映射。为什么?我不确定它是否按预期工作,但我确信它看起来不正确。坚持一个(我推荐Fluent API)。其次,我想,User
Payments
的{{1}}应该有两个导航属性。 User.Payments
并不意味着什么,您是希望用户付款还是通过一个导航属性向用户付款?。而且你必须只从一侧进行映射。最后,您的模型和映射应如下所示:
public class User
{
public int UserId { get; set; }
// Navigation properties
public virtual ICollection<Payment> PaymentsFromUser { get; set; }
public virtual ICollection<Payment> PaymentsToUser { get; set; }
}
public class UserConfiguration
: IEntityTypeConfiguration<User>
{
public UserConfiguration()
{
// Primary key
HasKey(m => m.UserId);
Property(m => m.PaymentId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
public class Payment
{
public int PaymentId { get; set; }
public int FromUserId { get; set; }
public int ToUserId { get; set; }
// Navigation properties
public virtual User FromUser { get; set; }
public virtual User ToUser { get; set; }
}
public class PaymentConfiguration
: IEntityTypeConfiguration<Payment>
{
public PaymentConfiguration()
{
// Primary key
HasKey(m => m.PaymentId);
Property(m => m.PaymentId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// Relationship mappings
HasRequired(m => m.FromUser)
.WithMany(m => m.PaymentsFromUser)
.HasForeignKey(m => m.FromUserId)
.WillCascadeOnDelete(true);
HasRequired(m => m.ToUser)
.WithMany(m => m.PaymentsToUser)
.HasForeignKey(m => m.ToUserId)
.WillCascadeOnDelete(true);
}
}
注意: virtual
关键字适用于Lazy loading
,如果您不需要,可以跳过。
现在它应该按预期工作。请记住测试如下:
Assert.AreEqual(user1.PaymentsFromUser.Count(), 1);
Assert.AreEqual(user2.PaymentsToUser.Count(), 1);
请注意,我认为user1
和user2
都由EntityFramework跟踪,因此EF可以将用户与付款相关联。