我在ASP.NET MVC 4中创建了一个网站。 它已经很久了,我有这个错误:发生了参照完整性约束违规。 我尝试更新数据库中的条目时。当有人想购买产品时,我需要更换购买的用户。
我有两个一对多的关系。
修改 这是我的用户类:
public class User
{
private string email, password, firstname, lastname;
private Adress shippingAdress, billingAdress;
private bool isConnected;
private List<Product> products;
//private List<Auction> auctions;
private long idShippingA, idBillingA;
public User()
{
products = new List<Product>();
}
/* public List<Auction> Auctions
{
get { return auctions; }
set { auctions = value; }
}
public void AddAuction(Auction auction)
{
if (auction != null)
auctions.Add(auction);
}*/
public long IdBillingA
{
get { return idBillingA; }
set
{
if (value < 0)
throw new ArgumentException("The id of the billing adress should not be negative");
idBillingA = value;
}
}
public long IdShippingA
{
get { return idShippingA; }
set
{
if (value < 0)
throw new ArgumentException("The id of the shipping adress should not be negative");
idShippingA = value;
}
}
public bool IsConnected
{
get { return isConnected; }
set { isConnected = value; }
}
public virtual List<Product> Products
{
get { return products; }
set
{
if (value == null)
throw new ArgumentNullException("The list of product should not be null");
products = value;
}
}
public Adress BillingAdress
{
get { return billingAdress; }
set
{
if (value == null)
throw new ArgumentNullException("The billing adress should not be null");
billingAdress = value;
}
}
public Adress ShippingAdress
{
get { return shippingAdress; }
set
{
if (value == null)
throw new ArgumentNullException("The shipping adress should not be null");
shippingAdress = value;
}
}
public string Password
{
get { return password; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The password should not be null or empty");
password = value;
}
}
public string Email
{
get { return email; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The email should not be null or empty");
email = value;
}
}
public string Lastname
{
get { return lastname; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The lastname should not be null or empty");
lastname = value;
}
}
public string Firstname
{
get { return firstname; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The fistname should not be null or empty");
firstname = value;
}
}
}
}
修改 这是我的产品类:
public class Product
{
private long id, strategyId;
private User userWhoSell;
private User userWhoBuy;
private string userWhoSellId, userWhoBuyId, name, description, urlPicture, isBought;
public string IsBought
{
get { return isBought; }
set { isBought = value; }
}
private SellStrategy strategy;
private float price;
private string strategyString;
public Product()
{
isBought = "F";
}
public float Price
{
get { return price; }
set
{
if (value < 0)
throw new ArgumentException("The price should not be negative");
price = value;
}
}
public string StrategyString
{
get { return strategyString; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The strategy string should not be null, empty or with white space");
strategyString = value;
}
}
public long StrategyId
{
get { return strategyId; }
set
{
if (value < 0)
throw new ArgumentException("The strategy id should not be negative");
strategyId = value;
}
}
public SellStrategy Strategy
{
get { return strategy; }
set
{
if (value == null)
throw new ArgumentNullException("The strategy should not be null");
strategy = value;
}
}
public string SellerId
{
get { return userWhoSellId; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The user id should not be null, empty or with white space");
userWhoSellId = value;
}
}
public string BuyerId
{
get { return userWhoBuyId; }
set
{
userWhoBuyId = value;
}
}
public string UrlPicture
{
get { return urlPicture; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The picture's url should not be null, empty or with white space");
urlPicture = value;
}
}
public long Id
{
get { return id; }
set
{
if (value < 0)
throw new ArgumentException("The id should not be negative");
id = value;
}
}
public string Description
{
get { return description; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The description should not be null, empty or with white space");
description = value;
}
}
public string Name
{
get { return name; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("The name should not be null, empty or with white space");
name = value;
}
}
public virtual User Buyer
{
get { return userWhoBuy; }
set
{
userWhoBuy = value;
}
}
public virtual User Seller
{
get { return userWhoSell; }
set
{
if (value == null)
throw new ArgumentNullException("The user should not be null");
userWhoSell = value;
}
}
}
修改 这是我的背景:
public class Context : DbContext
{
public Context(string connString)
: base(connString) { }
public DbSet<User> Users { get; set; }
public DbSet<Adress> Adress { get; set; }
public DbSet<Product> Products { get; set; }
//public DbSet<Auction> Auctions { get; set; }
public DbSet<SellStrategy> Strategies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().HasKey<string>(u => u.Email);
modelBuilder.Entity<Adress>().HasKey<long>(a => a.Id);
modelBuilder.Entity<Product>().HasKey<long>(p => p.Id);
modelBuilder.Entity<Auction>().HasKey<long>(au => au.Id);
modelBuilder.Entity<Product>()
.HasRequired(p => p.Seller)
.WithMany(u => u.Products)
.HasForeignKey(p => p.SellerId)
.WillCascadeOnDelete(false);
// Otherwise you might get a "cascade causes cycles" error
modelBuilder.Entity<Product>()
.HasOptional(p => p.Buyer)
.WithMany() // No reverse navigation property
.HasForeignKey(p => p.BuyerId)
.WillCascadeOnDelete(false);
// modelBuilder.Entity<Auction>().HasMany<User>(au => au.Users).WithMany(u => u.Auctions);
// modelBuilder.Entity<Auction>().HasRequired(au => au.Product).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<User>().HasRequired(u => u.BillingAdress).WithMany().HasForeignKey(u => u.IdBillingA).WillCascadeOnDelete(false);
modelBuilder.Entity<User>().HasRequired(u => u.ShippingAdress).WithMany().HasForeignKey(u => u.IdShippingA).WillCascadeOnDelete(false);
modelBuilder.Entity<User>().Ignore(u => u.IsConnected);
modelBuilder.Entity<Product>().HasRequired<SellStrategy>(p => p.Strategy).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<Product>().Ignore(p => p.StrategyString);
modelBuilder.Entity<Product>().Ignore(p => p.Price);
modelBuilder.Entity<SellStrategy>().Property(s => s.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<AuctionSelling>().HasKey<long>(a => a.Id);
modelBuilder.Entity<AuctionSelling>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("AuctionSelling");
});
modelBuilder.Entity<DirectSelling>().HasKey<long>(d => d.Id);
modelBuilder.Entity<DirectSelling>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("DirectSelling");
});
modelBuilder.Entity<SellStrategy>().Property(s => s.SoldDate).IsOptional();
}
}
修改 当我尝试更新我的产品时:
public void UpDateProduct(Product product)
{
using(Context context = new Context(connectionString))
{
try
{
Product p = GetById(product.Id);
//context.Products.Attach(p);
p.BuyerId = product.BuyerId;
p.Buyer = product.Buyer;
p.IsBought = "T";
context.Entry(p).State = EntityState.Modified;
context.SaveChanges();
}
catch (Exception ex)
{
}
}
}
这是
行context.Entry(p).State = EntityState.Modified;
引发错误。
这是完整的错误
发生了参照完整性约束违规:&#39; User.Email&#39;的属性值。在一段关系的一端与&#39; Product.BuyerId&#39;的属性值不匹配。在另一端。
当我执行context.saveChanges时,什么也没发生...... 我不知道该怎么做......我想哭... ^^ ... 非常感谢你提前了!
答案 0 :(得分:1)
这是由在构造函数中设置引用导航属性引起的。具体做法是:
userWhoSell = new User();
userWhoBuy = new User();
这意味着Product
开始有两个虚拟User
对象,您必须替换才能使它们变得有意义。否则EF可能会尝试保存这些虚拟对象。我很确定通过......
context.Entry(p).Entity.Buyer = product.Buyer;
...您实际设置了一个空的User
对象,其键值为no email
,而不是您之前设置的键值Product.BuyerId
。
我会说:在实体的构造函数中删除大多数这些初始化。初始化集合是有道理的。有时设置默认值(但不是主键值),但引用导航属性永远不会。另见:EF codefirst : Should I initialize navigation properties?
旁注:我也不会使用属性设置器进行验证。这就是数据注释的用途。尝试从数据库中实现实体时,这些异常可能会干扰EF。