【发布时间】:2014-12-20 12:26:34
【问题描述】:
我是 EF Code First 的新手,我正在尝试使用代码优先迁移为我的数据库添加一些数据。到目前为止,我已经设法解决了几个错误,但现在我被卡住了,无法找到答案。从我的代码更新数据库时,我遇到了两个问题。
我有几个对象,它们具有各种多对多和一对一的关系,有些对象最终会创建一个圆圈。当我尝试为数据库播种时,我不确定这是否是第二个问题的原因。
- 我遇到的第一个错误是:
A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column: 'LicenseId'.
有没有办法可以使用 db 生成的 id 作为外键?仅仅是我创建/插入对象的顺序吗? (见下面的种子代码)
如果我不在许可证中使用[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)],我会收到一个错误,提示无法隐式插入不是由数据库生成的 id。
public class License : Entity
{
[Key, ForeignKey("Customer")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int LicenseId { get; set; }
[Required(ErrorMessage = "Date Created name is required")]
public DateTime DateCreated { get; set; }
public virtual ICollection<ProductLicense> ProductLicenses { get; set; } // one License has many ProductLicenses
public virtual Customer Customer { get; set; } // one Customer has one License
}
public class Customer : Entity
{
[Key]
public int CustomerId { get; set;}
[Required(ErrorMessage = "Username is required")]
[Column(TypeName = "nvarchar")]
[MaxLength(500)]
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; } // one Customer has many users
public virtual License License { get; set; } // one Customer has one License
//public virtual ICollection<License> License { get; set; } // one Customer has many Licenses
}
- 如果我将 License-Customer 更改为多对多关系(我不希望这样做),我会收到以下错误:
Cannot insert duplicate key row in object 'dbo.Users' with unique index 'IX_Username'.
这些都是我的关系:
Customer -many-> User -many-> Role -many-> Permission -one- ProductLicense <-many- License -one- Customer
这是我在protected override void Seed(DAL.Models.Context context) 中一直使用的代码,在代码中创建对象,然后使用 AddOrUpdate:
// Default Customers - create
var customers = new[]{
new Customer { Name = "cust_a" },
new Customer { Name = "cust_b" },
new Customer { Name = "cust_c" }
};
// Default Licenses - create
var licenses = new[]{
new License { DateCreated = DateTime.Now.AddDays(-3), Customer = customers[0] },
new License { DateCreated = DateTime.Now.AddDays(-2), Customer = customers[1] },
new License { DateCreated = DateTime.Now.AddDays(-1), Customer = customers[2] }
};
// Default ProductLicenses - create, and add default licenses
var productLicenses = new[]{
new ProductLicense { LicenceType = LicenseType.Annual, StartDate = DateTime.Now, License = licenses[0] },
new ProductLicense { LicenceType = LicenseType.Monthly, StartDate = DateTime.Now, License = licenses[1] },
new ProductLicense { LicenceType = LicenseType.PAYG, StartDate = DateTime.Now, License = licenses[2] }
};
// Default Permissions - create, and add default product licenses
var permissions = new[]{
new Permission { Name = "Super_a", ProductLicense = productLicenses[0] },
new Permission { Name = "Access_b", ProductLicense = productLicenses[1] },
new Permission { Name = "Access_c", ProductLicense = productLicenses[2] }
};
// Default Roles - create, and add default permissions
var roles = new[]{
new Role { Name = "Super_a", Permissions = permissions.Where(x => x.Name.Contains("_a")).ToList() },
new Role { Name = "User_b", Permissions = permissions.Where(x => x.Name.Contains("_b")).ToList() },
new Role { Name = "User_c", Permissions = permissions.Where(x => x.Name.Contains("_c")).ToList() }
};
// Default Users - create, and add default roles
var users = new[]{
new User { Username = "user@_a.com", Password = GenerateDefaultPasswordHash(), Salt = _defaultSalt, Roles = roles.Where(x => x.Name.Contains("_a")).ToList() },
new User { Username = "user@_b.co.uk", Password = GenerateDefaultPasswordHash(), Salt = _defaultSalt, Roles = roles.Where(x => x.Name.Contains("_b")).ToList() },
new User { Username = "user@_c.com", Password = GenerateDefaultPasswordHash(), Salt = _defaultSalt, Roles = roles.Where(x => x.Name.Contains("_c")).ToList() }
};
// Default Customers - insert, with default users
foreach (var c in customers)
{
c.Users = users.Where(x => x.Username.Contains(c.Name.ToLower())).ToList();
context.Customers.AddOrUpdate(c);
}
我还尝试将//Default Customers - create 之后的第一部分更改为
// Default Customers - create and insert
context.Customers.AddOrUpdate(
u => u.Name,
new Customer { Name = "C6" },
new Customer { Name = "RAC" },
new Customer { Name = "HSBC" }
);
context.SaveChanges();
var customers = context.Customers.ToList();
非常感谢您对此的帮助,以便我可以为我的数据库添加适当的数据。
非常感谢您的帮助,很抱歉发了这么长的帖子。
--- 更新 ---
在以下 Chris Pratt 的出色回答之后,我现在收到以下错误:
Conflicting changes detected. This may happen when trying to insert multiple entities with the same key.
这是我用于播种和所有相关模型的新代码:https://gist.github.com/jacquibo/c19deb492ec3fff0b5a7
有人可以帮忙吗?
【问题讨论】:
标签: c# asp.net-mvc-4 ef-code-first entity-framework-6 entity-framework-migrations