2017-06-23 75 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