2017-06-23 72 views
0

我正在處理這個項目,我們首先給了一個數據庫與EF數據庫連接。查詢由ICollections連接的多個表

我正在嘗試檢索給定客戶的地址。

這裏是Customer類:

[DataContract] 
public partial class Customer 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Customer() 
    { 
     this.Orders = new HashSet<Order>(); 
     this.WishLists = new HashSet<WishList>(); 
     this.Addresses = new HashSet<Address>(); 
     this.Contacts = new HashSet<Contact>(); 
    } 

    [DataMember] 
    public int CustomerID { get; set; } 

    [DataMember] 
    public string UserName { get; set; } 

    [DataMember] 
    public string FirstName { get; set; } 

    [DataMember] 
    public string LastName { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<Order> Orders { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<WishList> WishLists { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<Address> Addresses { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<Contact> Contacts { get; set; } 
} 

和地址類:

[DataContract] 
public partial class Address 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Address() 
    { 
     this.Orders = new HashSet<Order>(); 
     this.Customers = new HashSet<Customer>(); 
     this.Employees = new HashSet<Employee>(); 
    } 

    [DataMember] 
    public int AddressID { get; set; } 

    [DataMember] 
    public int AddressType { get; set; } 

    [DataMember] 
    public string Street { get; set; } 

    [DataMember] 
    public string Suburb { get; set; } 

    [DataMember] 
    public string City { get; set; } 

    [DataMember] 
    public string PostalCode { get; set; } 

    [DataMember] 
    public string Country { get; set; } 

    [DataMember] 
    public AddressType AddressType1 { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<Order> Orders { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<Customer> Customers { get; set; } 

    [DataMember] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public ICollection<Employee> Employees { get; set; } 
} 

數據庫中的這兩個表由CustomerAddress表所連接EF已經變成了公衆的ICollection客戶{得到;組; }和公共ICollection地址{get;組; }。

我的目標是在我的MVC Web應用程序中顯示客戶的地址。但是,我在嘗試編寫LINQ查詢或等效項來檢索地址時遇到了很多麻煩。到目前爲止,我已經嘗試過:

// Return the details for current customer (this function works as expected) 
public Customer CurrentCustomer(string UserName) 
{ 
    Customer data = (from c in db.Customers 
        where c.UserName == UserName 
        select c).SingleOrDefault(); 

    return data; 
} 

// Return the address details for current customer (this function does not work) 
public Address GetAddress(string UserName) 
{ 
    // function to retrieve the CustomerID of the current customer 
    var customerID = CurrentCustomer(UserName).CustomerID; 

    Address data = db.Customers.Find(customerID).Addresses.FirstOrDefault(); 

    return address; 
} 

非常感謝您的幫助。我很努力地查詢沒有外鍵關係的兩個表。

回答

1

您無需首先找到Username的客戶,然後通過查找其地址。你可以用一個簡單的查詢來找到它。

要提取只是你的客戶的地址,改變你的方法是:

public List<Address> GetAddresses(string UserName) 
    { 
     var addresses = db.Customers.Where(p=> p.UserName == UserName).SelectMany(a=> a.Addresses).ToList(); 

     return addresses; 
    } 

它返回根據客戶的用戶名的地址列表。

,你可以用下面的方法只返回客戶的地址之一:

public Address GetAddress(string UserName) 
{ 
    var address = db.Customers.Where(p=> p.UserName == UserName).Select(a=> a.Addresses.FirstOrDefault()).FirstOrDefault(); 

    return address; 
} 

我希望這是有幫助的。

+0

謝謝。週一我回到課堂時我會嘗試。 – jonenz

+0

你想從這個方法的客戶的地址或所有地址? –

+0

我已經爲你寫了他們兩個。你可以用延遲加載的方式來開發它,但它有一些性能問題。對於你作爲學生這兩種方式是合理的。祝你好運 –

1

您必須集合使用虛擬爲EF爲導航屬性提供延遲加載,通過外鍵

[DataMember] 
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
public virtual ICollection<Address> Addresses { get; set; } 

之後,你可以使用這樣的查詢

public Address GetAddress(string UserName) 
{ 
    Address data = db.Customers.Find(c => c.UserName == UserName)?.Addresses?.FirstOrDefault(); 

    return address; 
} 
+0

感謝您的幫助。 – jonenz