2012-01-25 62 views
2

我试图使用LINQ to在Windows Phone 7.1的SQL模型以下关系:LINQ to SQL的多对多的关系插入和删除的问题

create table x (id INTEGER PRIMARY KEY AUTOINCREMENT, text STRING); 
create table y (id INTEGER PRIMARY KEY AUTOINCREMENT, text STRING); 
create table z (id INTEGER PRIMARY KEY AUTOINCREMENT, 
       x_id INTEGER NOT NULL, 
       y_id INTEGER NOT NULL, 
       FOREIGN KEY(x_id) REFERENCES x(id) ON DELETE CASCADE, 
       FOREIGN KEY(y_id) REFERENCES y(id) ON DELETE CASCADE); 

所以,如果我有它应该Z平台记录每当我删除id为x_id的x记录或者id为y_id的y记录时,都会被删除。

我有下面的C#代码(基于http://msdn.microsoft.com/en-us/library/hh286405(v=vs.92).aspx为例):

namespace linq2sql.test.program 
{ 
    public class MyDatabase : DataContext 
    { 
     public MyDatabase(string connectionString) 
      : base(connectionString) 
     { } 

     public Table<X> Xs; 
     public Table<Y> Ys; 
     public Table<Z> Zs; 
    } 

    public class BaseTable : INotifyPropertyChanged, INotifyPropertyChanging 
    { 
     // boring interface implementation omitted for brevity 
    } 

    [Table] 
    public class X : BaseTable 
    { 
     private int _id; 
     [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)] 
     public int Id 
     { 
      get { return _id; } 
      set 
      { 
       if (_id != value) 
       { 
        NotifyPropertyChanging("Id"); 
        _id = value; 
        NotifyPropertyChanged("Id"); 
       } 
      } 
     } 

     private EntitySet<Z> _zs; 
     [Association(Storage = "_zs", OtherKey = "_xId", ThisKey = "Id", DeleteRule="CASCADE")] 
     public EntitySet<Z> Zs 
     { 
      get { return this._zs; } 
      set { this._zs.Assign(value); } 
     } 

     public X() 
     { 
      _zs = new EntitySet<Z>(
       new Action<Z>(this.attach_z), 
       new Action<Z>(this.detach_z) 
       ); 
     } 

     private void attach_z(Z z) 
     { 
      NotifyPropertyChanging("Z"); 
      z.X = this; 
     } 

     private void detach_z(Z z) 
     { 
      NotifyPropertyChanging("Z"); 
      z.X = null; 
     } 
    } 

    [Table] 
    public class Y : BaseTable 
    { 
     // exactly the same as table X 
    } 

    [Table] 
    public class Z : BaseTable 
    { 
     private int _id; 
     [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)] 
     public int Id 
     { 
      get { return _id; } 
      set 
      { 
       if (_id != value) 
       { 
        NotifyPropertyChanging("Id"); 
        _id = value; 
        NotifyPropertyChanged("Id"); 
       } 
      } 
     } 

     [Column] 
     internal int _xId; 

     private EntityRef<X> _x; 
     [Association(Storage = "_x", ThisKey = "_xId", OtherKey = "Id", IsForeignKey = true)] 
     public X X 
     { 
      get { return _x.Entity; } 
      set 
      { 
       if (_x.Entity != value) 
       { 
        NotifyPropertyChanging("X"); 
        _x.Entity = value; 

        if (value != null) 
        { 
         _xId = value.Id; 
        } 

        NotifyPropertyChanged("X"); 
       } 
      } 
     } 

     [Column] 
     internal int _yId; 

     private EntityRef<Y> _y; 
     [Association(Storage = "_y", ThisKey = "_yId", OtherKey = "Id", IsForeignKey = true)] 
     public Y Y 
     { 
      get { return _y.Entity; } 
      set 
      { 
       if (_y.Entity != value) 
       { 
        NotifyPropertyChanging("Y"); 
        _y.Entity = value; 

        if (value != null) 
        { 
         _yId = value.Id; 
        } 

        NotifyPropertyChanged("Y"); 
       } 
      } 
     } 
    } 
} 

我开始对它进行测试和运行一分为二,可能有关,问题。下面插入代码的工作:

using (MyDatabase db = new MyDatabase(KDBConnectionString)) 
{ 
    if (!db.DatabaseExists()) 
    { 
     db.CreateDatabase(); 
    } 

    X x = new X(); 
    db.Xs.InsertOnSubmit(x); 

    Y y = new Y(); 
    db.Ys.InsertOnSubmit(y); 

    Z z = new Z(); 
    x.Zs.Add(z); 
    y.Zs.Add(z); 
    db.SubmitChanges(); 

    Assert.IsTrue(db.Xs.Count() == 1, "no x"); 
    Assert.IsTrue(db.Ys.Count() == 1, "no y"); 
    Assert.IsTrue(db.Zs.Count() == 1, "no z"); 

    Assert.IsTrue(db.Xs.First().Zs.Count() == 1, "no z in x"); 
    Assert.IsTrue(db.Ys.First().Zs.Count() == 1, "no z in y"); 
} 

但这个代码,我预计是等价的,不会:

using (MyDatabase db = new MyDatabase(KDBConnectionString)) 
{ 
    if (!db.DatabaseExists()) 
    { 
     db.CreateDatabase(); 
    } 

    X x = new X(); 
    db.Xs.InsertOnSubmit(x); 

    Y y = new Y(); 
    db.Ys.InsertOnSubmit(y); 

    Z z = new Z() { X = x, Y = y }; 
    db.Zs.InsertOnSubmit(z); 
    db.SubmitChanges(); 

    Assert.IsTrue(db.Xs.Count() == 1, "no x"); 
    Assert.IsTrue(db.Ys.Count() == 1, "no y"); 
    Assert.IsTrue(db.Zs.Count() == 1, "no z"); 

    Assert.IsTrue(db.Xs.First().Zs.Count() == 1, "no z in x"); // fails here 
    Assert.IsTrue(db.Ys.First().Zs.Count() == 1, "no z in y"); 
} 

级联删除如我所料不工作。这工作:

using (MyDatabase db = new MyDatabase(KDBConnectionString)) 
{ 
    if (!db.DatabaseExists()) 
    { 
     db.CreateDatabase(); 
    } 

    X x = new X(); 
    db.Xs.InsertOnSubmit(x); 

    Y y = new Y(); 
    db.Ys.InsertOnSubmit(y); 

    Z z = new Z(); 
    x.Zs.Add(z); 
    y.Zs.Add(z); 
    db.SubmitChanges(); 

    db.Zs.DeleteOnSubmit(z); 
    db.SubmitChanges(); 

    Assert.IsTrue(db.Zs.Count() == 0, "z not deleted"); 
    Assert.IsTrue(x.Zs.Count() == 0, "z not removed from x"); 
    Assert.IsTrue(y.Zs.Count() == 0, "z not removed from y"); 
} 

这不:

using (MyDatabase db = new MyDatabase(KDBConnectionString)) 
{ 
    if (!db.DatabaseExists()) 
    { 
     db.CreateDatabase(); 
    } 

    X x = new X(); 
    db.Xs.InsertOnSubmit(x); 

    Y y = new Y(); 
    db.Ys.InsertOnSubmit(y); 

    Z z = new Z(); 
    x.Zs.Add(z); 
    y.Zs.Add(z); 
    db.SubmitChanges(); 

    db.Xs.DeleteOnSubmit(x); 
    db.SubmitChanges(); 

    Assert.IsTrue(db.Zs.Count() == 0, "z not deleted"); // ...this works, so "CASCADE" parameter has some effect 
    Assert.IsTrue(y.Zs.Count() == 0, "z not removed from y"); // ... but fails here, so something is off 
} 

我想我有外键定义了一些简单的错误,但我找不到它我自己和我的谷歌赋今天是弱。所有的帮助表示赞赏。

回答

相关问题