【问题标题】:object references in LINQ to SQL are incorrectly saved or loadedLINQ to SQL 中的对象引用被错误地保存或加载
【发布时间】:2016-03-08 00:58:33
【问题描述】:

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

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

[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:\Temp\Testspace - Forum Database\database.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
            */
        }
    }
}

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

【问题讨论】:

    标签: c# sql linq linq-to-sql entityset


    【解决方案1】:

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

    [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;
            } 
        }
    }
    

    【讨论】:

      【解决方案2】:

      正如@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:\Temp\Testspace - Forum Database\database.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!
                      */
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-11
        • 1970-01-01
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        • 2010-12-03
        相关资源
        最近更新 更多