2013-11-28 94 views
1

在這個例子中,我有一個Customer可以有很多PhoneNumbers。這些對象:綁定DataGrid到EntitySet

客戶

[Table(Name = "Customers")] 
public class Customer : INotifyPropertyChanged 
{ 
    private String id; 

    private String givenName; 
    private String surname; 

    private EntitySet<PhoneNumber> phoneNumbers; 

    //INotifyPropertyChanged implementation was elided... 

    [Column(IsPrimaryKey=true, Storage="id", Name="Id", DbType="NVarChar(10) NOT NULL", CanBeNull=false)] 
    public String Id 
    { 
     get { return this.id; } 
     set 
     { 
      if (this.id != value) 
      { 
       this.id = value; 
       this.OnPropertyChanged("Id"); 
      } 
     } 
    } 

    [Column(Storage="givenName", Name="GivenName", DbType="NVarChar(50) NOT NULL", CanBeNull=false)] 
    public String GivenName 
    { 
     get { return this.givenName; } 
     set 
     { 
      if (this.givenName != value) 
      { 
       this.givenName = value; 
       this.OnPropertyChanged("GivenName"); 
      } 
     } 
    } 

    [Column(Storage="surname", Name="Surname", DbType="NVarChar(50) NOT NULL", CanBeNull=false)] 
    public String Surname 
    { 
     get { return this.surname; } 
     set 
     { 
      if (this.surname != value) 
      { 
       this.surname = value; 
       this.OnPropertyChanged("Surname"); 
      } 
     } 
    } 

    [Association(Name="FK_PhoneBook_Customers", Storage = "phoneNumbers", ThisKey="Id", OtherKey = "CustomerId")] 
    public EntitySet<PhoneNumber> PhoneNumbers 
    { 
     get 
     { 
      return this.phoneNumbers; 
     } 
     set 
     { 
      if (this.phoneNumbers!= value) 
      { 
       this.phoneNumbers.Assign(value); 
       this.OnPropertyChanged("PhoneNumbers"); 
      } 
     } 
    } 

    public Customer() { this.phoneNumbers = new EntitySet<PhoneNumber>(); } 
} 

[Table(Name = "PhoneBook")] 
public class PhoneNumber: INotifyPropertyChanged 
{ 

    private int id; 
    private String customerId; 
    private String number; 

    private EntityRef<Customer> customer; 

    //INotifyPropertyChanged implementation was elided... 

    [Column(IsPrimaryKey=true, IsDbGenerated=true, Storage="id", Name="Id", DbType="int", CanBeNull=false)] 
    public int Id 
    { 
     get { return this.id; } 
     private set 
     { 
      if (this.id != value) 
      { 
       this.id = value; 
       this.OnPropertyChanged("Id"); 
      } 
     } 
    } 

    [Column(Storage="customerId", Name="CustomerId", DbType="NVarChar(10) NOT NULL", CanBeNull=false)] 
    public String CustomerId 
    { 
     get { return this.customerId; } 
     set 
     { 
      if (this.customerId != value) 
      { 
       this.customerId = value; 
       this.OnPropertyChanged("CustomerId"); 
      } 
     } 
    } 

    [Column(Storage="number", Name="Number", DbType="NVarChar(10) NOT NULL", CanBeNull=false)] 
    public String Number 
    { 
     get { return this.number; } 
     set 
     { 
      if (this.number != value) 
      { 
       this.number = value; 
       this.OnPropertyChanged("Number"); 
      } 
     } 
    } 

    [Association(IsForeignKey=true, Name="FK_PhoneBook_Customers", ThisKey="CustomerId", OtherKey = "Id")] 
    public Customer Customer 
    { 
     get { return this.customer.Entity; } 
     set { this.customer.Entity = value; } 
    } 

    public PhoneNumber() { this.customer = new EntityRef<Customer>(); } 
} 

我創建了一個DataContext的,並得到了客戶(簡本)的電話號碼:

db = new DataContext(@"server=WIN-EL78137MUMS\SQLEXPRESS;database=SandBox;integrated security=SSPI"); 

// Get a typed table to run queries. 
customers = db.GetTable<Customer>(); 

custQuery = 
    from cust in customers 
    orderby cust.Id 
    select cust; 

Customer = custQuery.Skip(5).Take(1).First(); 

進入XAML我添加了DataGrid並將其綁定到CustomerNumber的PhoneNumbers屬性。

<DataGrid ItemsSource="{Binding PhoneNumbers}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Id" Binding="{Binding Id, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" /> 
     <DataGridTextColumn Header="CustomerId" Binding="{Binding CustomerId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
     <DataGridTextColumn Header="Number" Binding="{Binding Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    </DataGrid.Columns> 
</DataGrid> 

對不起長介紹,這裏是我的一些問題,以及問題 - 當我嘗試添加一個新的電話號碼輸入到電網,並調用db.SubmitChanges()我得到以下錯誤信息:「試圖刪除Customer和PhoneNumber之間的關係,但是,其中一個關係的外鍵(PhoneNumber.CustomerId)不能設置爲null。「現在,我不希望用戶在需要添加電話號碼時不斷地寫入客戶ID,因爲正確的客戶已被選中,並且正在嘗試爲他的號碼集添加另一個號碼。這可以/應該如何完成?
其他問題是:

  1. 看來,新線不會被添加,直到輸入被按下,如果我輸入電話號碼,並在之後的是點擊一個按鈕調用db.SubmitChanges(),沒什麼會發生(所有三個集合[插入/更新/刪除]將爲空)。
  2. 我必須在PhoneNumber中保存一個EntityRef嗎?在野外有很多例子根本沒有,有人提到它是一對一的連接工具。
  3. 無論哪種方式,將EntityRef定義爲IsForeignKey = true都有點奇怪,聽起來對PhoneNumber.CustomerId應該定義爲ForeignKey更合理,但是當我試圖用[Association (IsForeignKey = true,Name =「FK_AddressBook_Customers」,ThisKey =「CustomerId」,OtherKey =「Id」)]我在應用程序啓動時出現此錯誤「無法找到類型爲'String'的鍵'Id'的鍵成員'Id' '。關鍵字可能是錯誤的,或'字符串'的字段或屬性已更改名稱「。我沒有在互聯網上找到任何有用的東西。它應該以另一種方式標記嗎?它應該被標記嗎?
  4. 我是否必須(或應該?)用兩個名稱(EntitySet和EntityRef)來命名外鍵(使用一個名稱(如我在另一個示例中看到的並在此處使用相同方法)?

回答

0

那麼,主要問題的答案很簡單,在PhoneNumber中的Association屬性中,我忘記了Storage屬性。正確的屬性定義如下:

[Association(IsForeignKey=true, Name="FK_PhoneBook_Customers", Storage="customer", ThisKey="CustomerId", OtherKey = "Id")] 
public Customer Customer 
{ 
    get { return this.customer.Entity; } 
    set { this.customer.Entity = value; } 
} 

回答第二個問題是「否」,其實沒有它我甚至不會面臨的主要問題都沒有。但由於某些原因Visual Studio創建了這個反向引用。如果你們任何人都知道它爲什麼會有用,請分享你的想法。
第三個問題的答案也是「不,它不應該被標記」。一旦所有東西都開始工作,並且沒有任何附加到PhoneNumber.CustomerId屬性的關聯屬性,就會很明顯。
我也對第四個問題有了部分回答 - 「不,我不必從兩端都給出相同的名稱 - 它將繼續以不同的名稱工作」,但可能是我應該給出相同的名稱(再次,VS命名它們完全相同),因爲一些未知和不必要的後果。請再次提醒。