我正在尝试构建一个维持三向关系的系统。但是当我进入关系的第二个实例时,我得到了一个例外。
这是基本代码
public class Role
{
protected Role() { }
public Role(string id, string description) : this()
{
Id = id;
Description = description;
}
public string Id { get; set; }
public string Description { get; set; }
}
public abstract class Entity
{
public Guid EntityId { get; private set; }
}
public class Project : Entity
{
protected Project()
{
UserProjectRoles = new Collection<UserProjectRole>();
}
public Project(string id, string description, string connectionString)
{
Id = id;
Description = description;
ConnectionString = connectionString;
}
public string Id { get; private set; }
public string Description { get; private set; }
public string ConnectionString { get; private set; }
public virtual ICollection<UserProjectRole> UserProjectRoles { get; private set; }
public IEnumerable<User> Users { get { return UserProjectRoles.Select(x => x.User).Distinct(); } }
}
public class User : Entity
{
protected User()
{
UserProjectRoles = new Collection<UserProjectRole>();
}
public User(string uniqueName)
: this()
{
UniqueName = uniqueName;
}
public string UniqueName { get; set; }
public virtual ICollection<UserProjectRole> UserProjectRoles { get; private set; }
public IEnumerable<Project> Projects { get { return UserProjectRoles.Select(x => x.Project).Distinct(); } }
}
public class UserProjectRole
{
protected UserProjectRole() { }
public UserProjectRole(Project project, User user, Role role)
{
Project = project;
User = user;
Role = role;
}
public Guid ProjectId { get; private set; }
public Guid UserId { get; private set; }
public string RoleId { get; private set; }
public Project Project { get; private set; }
public User User { get; private set; }
public Role Role { get; private set; }
}
public class MasterContext : DbContext
{
public MasterContext(string connectionString) : base(connectionString) { }
public IDbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Entity>().HasKey(e => e.EntityId);
modelBuilder.Entity<Entity>().Property(e => e.EntityId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Project>().Map(u => u.MapInheritedProperties()).ToTable("Projects");
modelBuilder.Entity<User>().Map(p => p.MapInheritedProperties()).ToTable("Users");
modelBuilder.Entity<Role>().HasKey(r => r.Id);
modelBuilder.Entity<UserProjectRole>().HasKey(x => new { x.ProjectId, x.UserId, x.RoleId });
modelBuilder.Entity<UserProjectRole>().HasRequired(x => x.User).WithMany(u => u.UserProjectRoles).HasForeignKey(x => x.UserId).WillCascadeOnDelete(false);
modelBuilder.Entity<UserProjectRole>().HasRequired(x => x.Project).WithMany(p => p.UserProjectRoles).HasForeignKey(x => x.ProjectId).WillCascadeOnDelete(false);
modelBuilder.Entity<UserProjectRole>().HasRequired(x => x.Role).WithMany().HasForeignKey(x => x.RoleId).WillCascadeOnDelete(false);
}
}
这是一个演示错误的测试用例。
[TestFixture]
public class EFTest
{
private const string MasterConnectionString =
"Data Source=localhost;Initial Catalog=TheDatabase;Integrated Security=True;";
private static readonly Role DataCollector = new Role("1", "Data Collector");
private static readonly Role Manager = new Role("2", "Manager");
[Test]
public void TheTest()
{
var user = new User("Tim the Enchanter");
var project = new Project("Foo", "Bar", "Another Connection string");
Database.SetInitializer(new DropCreateDatabaseAlways<MasterContext>());
using (var masterContext = new MasterContext(MasterConnectionString))
{
user.UserProjectRoles.Add(new UserProjectRole(project, user, DataCollector));
masterContext.Users.Add(user);
masterContext.SaveChanges();
}
Database.SetInitializer(new CreateDatabaseIfNotExists<MasterContext>());
using (var masterContext = new MasterContext(MasterConnectionString))
{
var u = masterContext.Users.First();
var p = u.Projects.First();
u.UserProjectRoles.Add(new UserProjectRole(p, u, Manager));
masterContext.SaveChanges();
}
}
}
当我运行该测试时,我收到以下错误:
System.Data.Entity.Infrastructure.DbUpdateException:错误 更新条目时发生。查看内部异常 细节。 ----&GT; System.Data.UpdateException:发生错误 更新条目。有关详细信息,请参阅内部异常----&GT; System.Data.SqlClient.SqlException:INSERT语句冲突 使用FOREIGN KEY约束 “FK_dbo.UserProjectRoles_dbo.Projects_ProjectId”。冲突 发生在数据库“Dev_Local_Master”,表“dbo.Projects”,列中 'ENTITYID'。声明已经终止。
答案 0 :(得分:0)
事实证明,UserProjectRole上的用户,项目和角色都需要是虚拟的才能正常工作。
错误信息在解决这个问题上有点不太有用。