We have found an issue in DataObjects 5.0.1 related to many to many relationships.
Given the classes "Student" and "Course" where Students can participate in multiple Courses and a Course has multiple students. The junction table "Student-Courses-Course" is automatically created by DO and contains the Student Id/TypeId, Course Id/TypeId and TypeId columns. When attempting to add a Course to the Student's "Courses" property or vice versa, the insert fails because rather than passing the Student or Course TypeId it passes the TypeId of the "Student-Courses-Course" entity which fails with a foreign key constraint:
Xtensive.Orm.ReferentialConstraintViolationException : SQL error occured.
Storage error details 'Entity: Student;'
SQL error details 'Type: ReferentialConstraintViolation; Database: Tests; Table: Student; Constraint: FK_Student-Courses-Course_Master_Student;'
Query 'INSERT INTO [dbo].[BaseEntity] ([Id], [TypeId]) VALUES (@p1_0, @p1_1);
INSERT INTO [dbo].[Student] ([Id], [TypeId]) VALUES (@p1_0, @p1_1);
INSERT INTO [dbo].[BaseEntity] ([Id], [TypeId]) VALUES (@p2_0, @p2_1);
INSERT INTO [dbo].[Course] ([Id], [TypeId]) VALUES (@p2_0, @p2_1);
INSERT INTO [dbo].[Student-Courses-Course] ([Student.Id], [Student.TypeId], [Course.Id], [Course.TypeId], [TypeId]) VALUES (@p3_0, @p3_1, @p3_2, @p3_3, @p3_4); [p1_0='1';p1_1='102';p2_0='2';p2_1='101';p3_0='1';p3_1='103';p3_2='2';p3_3='101';p3_4='0']'
Original message 'The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Student-Courses-Course_Master_Student". The conflict occurred in database "Tests", table "dbo.Student".
The statement has been terminated.'
To reproduce (please note this issue occurs with or without the bidirectional assocation):
[HierarchyRoot(IncludeTypeId = true, Clustered = true, InheritanceSchema = InheritanceSchema.ClassTable)]
public abstract class BaseEntity:Entity
{
[Field]
[Key(Position = 0)]
[FieldMapping("Id")]
public int Id { get; private set; }
}
[TableMapping("Student")]
public class Student:BaseEntity
{
[Field()]
[FieldMapping("Courses")]
public EntitySet<Course> Courses { get; private set; }
}
[TableMapping("Course")]
public class Course:BaseEntity
{
[Field()]
[FieldMapping("Students")]
[Association(PairTo = "Courses", OnOwnerRemove = OnRemoveAction.Clear, OnTargetRemove = OnRemoveAction.Clear)]
public EntitySet<Student> Students { get; private set; }
}
[TestFixture]
public class Test
{
[Test]
public void TestManyToMany()
{
var config = new DomainConfiguration("sqlserver",
"Data Source=localhost; Initial Catalog=Tests; " +
"Integrated Security=True; MultipleActiveResultSets=true;");
config.Types.Register(typeof (BaseEntity).Assembly);
config.UpgradeMode = DomainUpgradeMode.Recreate;
var domain = Domain.Build(config);
using (var session = domain.OpenSession())
{
session.Activate();
using (var trans = session.OpenTransaction())
{
Student student1 = new Student();
Course course1 = new Course();
student1.Courses.Add(course1);
//course1.Students.Add(student1);
trans.Complete();
}
}
}
}
asked
Aug 21 '14 at 14:33
DennisDre
7●2●2●4