LINQ to SQL 中的对象引用保存或加载不正确



我试图在彼此之间存储和重新加载对象及其引用。问题是当我从数据库中重新加载数据时,引用设置不正确。

下面是描述问题的示例代码。我在代码中注释了输出的解释状态和真实状态。

[Table(Name = "ClassA")]
public class ClassA
{
    public ClassA()
    {
        LinksToClassB = new EntitySet<ClassB>();
    }
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY")]
    public int ID { get; set; }
    [Association]
    public EntitySet<ClassB> LinksToClassB { get; set; } //=> 1 to n cardinality
    [Association]
    public ClassB OneLinkToClassB { get; set; }//=> 1 to 1 cardinality
}

[Table(Name = "ClassB")]
public class ClassB
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY")]
    public int ID { get; set; }
    [Column(CanBeNull = true)]
    public string Name { get; set; }
}
public class DatabaseContext : DataContext
{
    public Table<ClassA> ClassATable;
    public Table<ClassB> ClassBTable;
    public DatabaseContext(string connection) : base(connection) { }
}

[TestClass]
public class Test
{
    string path = @"F:TempTestspace - Forum Databasedatabase.mdf";//path to database
    [TestMethod]
    public void TestMethod()
    {
        //creates Database
        DatabaseContext context = new DatabaseContext(path);
        if (context.DatabaseExists())//Delete if exists
        {
            context.DeleteDatabase();
        }
        context.CreateDatabase();
        ClassB b1 = new ClassB(); b1.Name = "name 1";
        ClassB b2 = new ClassB(); b2.Name = "name 2";
        ClassB b3 = new ClassB(); b3.Name = "name 3";
        ClassA a = new ClassA();
        //now the references will be added to the object a
        //in 1-n references
        a.LinksToClassB.Add(b1);
        a.LinksToClassB.Add(b2);
        a.LinksToClassB.Add(b3);
        //and the has-one reference (OneLinkToClassB)
        a.OneLinkToClassB = b1;

        context.ClassATable.InsertOnSubmit(a);
        context.SubmitChanges(); //store in database

        //now the database will be reloaded
        context = new DatabaseContext(path);

        //Check if all ClassB objects were correctly stored and reloaded
        foreach (ClassB x in context.ClassBTable)
        {
            Console.WriteLine(x.ID + "; " + x.Name);
            /*    
                -> expected output:
                    1; name 1
                    2; name 2
                    3; name 3
                -> real output
                    1; name 1
                    2; name 2
                    3; name 3
                -> check!
            */
        }
        //check if all ClassA objects were correctly stored and reloaded
        foreach (ClassA x in context.ClassATable)//context.ClassATable has only one entry
        {
            Console.WriteLine("check of entitys set");
            //check of 1-n references
            foreach (ClassB b in x.LinksToClassB)
            {
                Console.WriteLine(x.ID + " has a link to " + b.ID + ", " + b.Name);
                /*
                    -> expected output:
                        1 has a link to 1, name 1
                        1 has a link to 2, name 2
                        1 has a link to 3, name 3
                    -> real output
                        1 has a link to 1, name 1
                    -> doesn't match...
                */
            }

            Console.WriteLine("check of single link");
            //check of 1-1 reference
            Console.WriteLine(x.ID + " has a link to " + x.OneLinkToClassB.ID + ", " + x.OneLinkToClassB.Name);
            /*
                    -> expected output:
                        1 has a link to 1, name 1
                    -> real output
                        this line throws an NullReferenceException
            */
        }
    }
}

我希望任何人都可以给我一个提示,如何在我的代码:)解决这个错误

除非省略,否则您的父/子关联似乎丢失了。

[Table(Name = "ClassA")]
public class ClassA
{
    public ClassA()
    {
        LinksToClassB = new EntitySet<ClassB>();
    }
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY")]
    public int ID { get; set; }
    [Association(ThisKey="ID", OtherKey="ClassAId")]
    public EntitySet<ClassB> LinksToClassB { get; set; } //=> 1 to n cardinality
    [Association]
    public ClassB OneLinkToClassB { get; set; }//=> 1 to 1 cardinality
}

[Table(Name = "ClassB")]
public class ClassB
{
    private EntityRef<ClassA> _classA = default(EntityRef<ClassA>);
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY")]
    public int ID { get; set; }
    [Column(CanBeNull = true)]
    public string Name { get; set; }
    [Column(CanBeNull = false)]
    public int ClassAId { get; set; }
    [Association(ThisKey = "ClassAId", OtherKey = "ID", IsForeignKey = true)]
    public ClassA ClassA {
        get
        {
            return _classA.Entity;
        }
        set {
            // property changed implementation omitted for brevity...
            _classA.Entity = value;
        } 
    }
}

>正如@Nick所说,"父/子关联缺失"。现在完整的更改代码:

[Table(Name = "ClassA")]
public class ClassA
{
    public ClassA()
    {
        LinksToClassB = new EntitySet<ClassB>();
    }
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    private int ID;
    [Association(ThisKey = "ID", OtherKey = "ClassAId")]
    private EntitySet<ClassB> LinksToClassB;//=> 1 to n cardinality
    public void addLink(ClassB x)
    {
        LinksToClassB.Add(x);
        x.setLink(this);
    }
    public HashSet<ClassB> getLinks()
    {
        HashSet<ClassB> collection = new HashSet<ClassB>();
        foreach(ClassB x in LinksToClassB)
        {
            collection.Add(x);
        }
        return collection;
    }
}

[Table(Name = "ClassB")]
public class ClassB
{
    private EntityRef<ClassA> _classA = default(EntityRef<ClassA>);
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY")]
    public int ID { get; set; }
    [Column(CanBeNull = true)]
    public string Name { get; set; }
    [Column(CanBeNull = false)]
    private int ClassAId { get; set; }
    [Association(ThisKey = "ClassAId", OtherKey = "ID", IsForeignKey = true)]
    private ClassA ClassA
    {
        get
        {
            return _classA.Entity;
        }
        set
        {
            _classA.Entity = value;
        }
    }
    private ClassA getLink()
    {
        return _classA.Entity;
    }
    public void setLink(ClassA x)
    {
        _classA.Entity = x;
    }
}
public class DatabaseContext : DataContext
{
    public Table<ClassA> ClassATable;
    public Table<ClassB> ClassBTable;
    public DatabaseContext(string connection) : base(connection) { }
}

[TestClass]
public class Test
{
    string path = @"F:TempTestspace - Forum Databasedatabase.mdf";//path to database
    [TestMethod]
    public void TestMethod()
    {
        //creates Database
        DatabaseContext context = new DatabaseContext(path);
        if (context.DatabaseExists())//Delete if exists
        {
            context.DeleteDatabase();
        }
        context.CreateDatabase();
        ClassB b1 = new ClassB(); b1.Name = "name 1";
        ClassB b2 = new ClassB(); b2.Name = "name 2";
        ClassB b3 = new ClassB(); b3.Name = "name 3";
        ClassA a = new ClassA();
        //now the references will be added to the object a
        //in 1-n references
        a.addLink(b1);
        a.addLink(b2);
        a.addLink(b3);
        context.ClassATable.InsertOnSubmit(a);
        context.SubmitChanges(); //store in database

        //now the database will be reloaded
        context = new DatabaseContext(path);

        //Check if all ClassB objects were correctly stored and reloaded

        foreach (ClassB x in context.ClassBTable)
        {
            Console.WriteLine(x.ID + "; " + x.Name);
            /*    
                -> expected output:
                    1; name 1
                    2; name 2
                    3; name 3
                -> real output
                    1; name 1
                    2; name 2
                    3; name 3
                -> check!
            */
        }
        //check if all ClassA objects were correctly stored and reloaded
        foreach (ClassA x in context.ClassATable)//context.ClassATable has only one entry
        {
            Console.WriteLine("check of entitys set");
            //check of 1-n references
            foreach (ClassB b in x.getLinks())
            {
                Console.WriteLine(b.ID + " has a link to " + b.ID + ", " + b.Name);
                /*
                    -> expected output:
                        1 has a link to 1, name 1
                        1 has a link to 2, name 2
                        1 has a link to 3, name 3
                    -> real output
                        1 has a link to 1, name 1
                        1 has a link to 2, name 2
                        1 has a link to 3, name 3
                    -> check!
                */
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新