集成ASP.NET Identity时Customer类Claims属性非导航属性报错排查
问题:ASP.NET Identity集成Customer表时重复插入报错
尝试在现有项目中集成ASP.NET Identity,使用Customer表存储用户,Customer类代码如下:
public partial class Customer : IdentityUser<int, CustomerLogin, AspNetRole, CustomerClaim> { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Customer() { this.Quotes = new HashSet<Quote>(); this.Bookings = new HashSet<Booking>(); this.CustomerClaims = new HashSet<CustomerClaim>(); this.CustomerLogins = new HashSet<CustomerLogin>(); this.AspNetRoles = new HashSet<AspNetRole>(); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<Customer, int> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } public int Id { get; set; } public string Password { get; set; } public System.DateTime CreationDate { get; set; } public System.DateTime UpdateDate { get; set; } public override string UserName { get; set; } public override ICollection<CustomerClaim> Claims => this.CustomerClaims; public virtual Country Country { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Quote> Quotes { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Booking> Bookings { get; set; } public virtual Location Location { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<CustomerClaim> CustomerClaims { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<CustomerLogin> CustomerLogins { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<AspNetRole> AspNetRoles { get; set; } }
首次插入用户成功,但再次插入时触发错误:
The 'Claims' property on the 'Customer' type is not a navigation property. The Reference and Collection methods can only be used with navigation properties. Use the Property or ComplexProperty method.
解决方案
问题出在重写的Claims属性上:你使用表达式体(=> this.CustomerClaims)实现了只读属性,EF无法将其识别为合法的导航属性,而ASP.NET Identity内部会尝试将Claims作为导航属性处理,导致重复插入时出错。
修复方法:
- 将
Claims属性改为标准的可读写属性,直接关联到CustomerClaims字段:
public override ICollection<CustomerClaim> Claims { get => CustomerClaims; set => CustomerClaims = value; }
或者传统写法:
public override ICollection<CustomerClaim> Claims { get { return CustomerClaims; } set { CustomerClaims = value; } }
同时检查你的DbContext配置:确保只对CustomerClaims配置导航关系,不要错误地将Claims当作导航属性进行Fluent API配置。
内容的提问来源于stack exchange,提问作者A.HADDAD
相关产品推荐
相关产品推荐

