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's gravatar image

DennisDre
7224

edited Aug 21 '14 at 15:08


One Answer:

Hello Dennis

Thank you for you bug report. We fix it in next version of DO.

answered Aug 22 '14 at 03:55

Alexey%20Kulakov's gravatar image

Alexey Kulakov
77225

Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA