Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 跟踪对象关系列表的最佳方法是什么_C#_.net_List - Fatal编程技术网

C# 跟踪对象关系列表的最佳方法是什么

C# 跟踪对象关系列表的最佳方法是什么,c#,.net,list,C#,.net,List,假设示例:我的内存中有一个客户列表和一个产品列表。我希望能够访问每个客户购买的产品以及购买特定产品的客户: class Customer { public List<Product> Products { get; set; } } class Product { public List<Customer> CustomersWhoBoughtThis { get; set; } } var customers = new List<Custom

假设示例:我的内存中有一个客户列表和一个产品列表。我希望能够访问每个客户购买的产品以及购买特定产品的客户:

class Customer
{
    public List<Product> Products { get; set; }
}
class Product
{
    public List<Customer> CustomersWhoBoughtThis { get; set; }
}


var customers = new List<Customer>();
var products = new List<Product>();

//add the customers
var customer1 = new Customer();
customers.Add(customer1);
var customer2 = new Customer();
customers.Add(customer2);

//add the products
var product1 = new Product();
products.Add(product1);
var product2 = new Product();
products.Add(product2);

//add a purchased product for customer1
customer1.Products.Add(product1);

//How do I get customer1 from product1?
foreach (var customerWhoBoughtProduct1 in product1.CustomersWhoBoughtThis)
{
    //do something
}
class客户
{
公共列表产品{get;set;}
}
类产品
{
公共列表customerswhobughtthis{get;set;}
}
var customers=新列表();
var products=新列表();
//添加客户
var customer1=新客户();
customers.Add(customer1);
var customer2=新客户();
customers.Add(customer2);
//添加产品
var product1=新产品();
产品。添加(产品1);
var product2=新产品();
产品。添加(产品2);
//为客户添加已购买的产品1
customer1.Products.Add(product1);
//如何从product1获取customer1?
foreach(product1.CustomerWhoBughtThis中的var CustomerWhoBughtProduct1)
{
//做点什么
}
我可以手动将客户添加到产品的
Customers whobughtthis
列表中,但我觉得这很容易出错,因为您可能会忘记在某个地方执行此操作

是否有更好的实现方法?可能是某种处理功能的包装类,但我不确定它将如何实现。有什么建议吗


谢谢

创建一个同时执行这两个操作的方法

void PairCustomerWithProduct(Customer customer, Product product)
{
    customer.Products.Add(product);
    product.CustomersWhoBoughtThis.Add(customer);
}
无论何时,当您需要将产品与客户配对时,请调用此方法。

您可以尝试这种方法

Class Customer{listCustomer>} 
-保存客户信息 类产品{list} -保存产品信息

再添加一个类以维护该组合

Class Sale{ public Customer, public Product }
还有一个类包含SoldProducts列表

Class SoldProduct{ list<Sale> }
Class SoldProduct{list}

我不会公开
列表
,而是返回数组或序列。公开添加/删除产品的方法

class Customer
{
    private List<Product> Products { get; set; }
    public void AddProduct(Product product)
    {
       Products.Add(product);
       if(!product.CustomersWhoBoughtThis.Contains(this))
           product.CustomersWhoBoughtThis.Add(this);
    }

    public void RemoveProduct(Product product)
    {
       Products.Remove(product);
       if(product.CustomersWhoBoughtThis.Contains(this))
           product.CustomersWhoBoughtThis.Remove(this);
    }

    public IEnumerable<Product> GetProducts()
    {
       return Products;
    }
}
class客户
{
私有列表产品{get;set;}
公共产品(产品)
{
产品。添加(产品);
如果(!product.customerswhobughtthis.Contains(this))
product.customerswhobughtthis.Add(this);
}
公共无效移除产品(产品产品)
{
产品。移除(产品);
if(product.customerswhobughtthis.Contains(this))
product.Customerwhobughtthis.Remove(此);
}
公共IEnumerable GetProducts()
{
退货产品;
}
}

您可以定义一些包装类,或者实现自己的
IList
接口,然后可以实现自己的事件支持通知。然而,使用内置的东西要简单得多。我将使用一个
BindingList
,它有一个名为
ListChanged
的事件,允许您获取一些通知,包括添加项目的通知。请尝试以下代码:

class Customer {
  public Customer(){
    Products = new BindingList<Product>();
    Products.ListChanged += (s,e) => {
       if(e.ListChangedType == ListChangedType.ItemAdded){
         Products[e.NewIndex].CustomersWhoBoughtThis.Add(this);
       }
    };
  }
  public BindingList<Product> Products { get; set; }
}
class客户{
公众客户(){
Products=新绑定列表();
Products.ListChanged+=(s,e)=>{
如果(e.ListChangedType==ListChangedType.ItemAdded){
产品[e.NewIndex].CustomerWhobughtThis.Add(此);
}
};
}
公共绑定列表产品{get;set;}
}

创建一个关系类

注意:我没有包括错误处理,只是基本的想法。还请注意,关系类(对于一对多关系)可以很容易地进行泛型,并可用于任何类型的关系。我把它放在混凝土上,让它更清楚

class Customer
{
  public List<Products> Products 
  { 
     get { return CustomerProductRelationship.CustomerProducts[this];}
     set 
     {
        CustomerProductRelationship.AddPair(value, this);
     }
}

class Product
{
  public List<Products> Products 
  { 
     get { return CustomerProductRelationship.ProductCustomers[this];}
     set 
     {
        CustomerProductRelationship.AddPair(this, value);
     }
  }
}

static class CustomerProductRelationship
{
  public static Dictionary<Customer, List<Product>> CustomerProducts;
  public static Dictionary<Product, List<Customer> ProductCustomers;

  public static AddPair(Product product, Customer customer)
  {
       if (!CustomerProducts.Contains(customer))
          CustomerProducts.Add(customer, new List<Product>);

       CustomerProducts[customer].Add(product);

       if (!ProductCustomers.Contains(product))
          ProductCustomers.Add(product, new List<Customers>);

       CustomerProducts[product].Add(customer);
   }
}
class客户
{
公开上市产品
{ 
获取{return CustomerProductRelationship.CustomerProducts[this];}
设置
{
CustomerProductRelationship.AddPair(值,this);
}
}
类产品
{
公开上市产品
{ 
获取{return CustomerProductRelationship.ProductCustomers[this];}
设置
{
CustomerProductRelationship.AddPair(这个值);
}
}
}
静态类CustomerProduct关系
{
公共静态词典客户产品;

公共静态字典通常,当我有一个循环关系时,我会指定其中一个实体作为关系的“所有者”。所有者负责管理关系,因此任何用于管理的代码都应该封装在其中

在这种情况下,由于客户实际执行了操作(客户购买了产品),因此最好将customer类指定为关系所有者

因此,产品类别将为:

public class Product
{
  //other product properties

  //field for the customers list
  private List<Customer> customers = new List<Customer>();

  //read-only property for outside access
  public IEnumerable<Customer> Customers 
  {
    get { return customers; }
  }

  //internal method that will only be called by the customer class
  internal void AddCustomer(Customer customer)
  {
    customers.Add(customer);
  }

  //internal method that will only be called by the customer class
  internal void RemoveCustomer(Customer customer)
  {
    customers.Remove(customer);
  }
}
并且引用设置正确。此外,外部用户(来自另一个程序集)将无法调用
product1.AddCustomer


另外,请务必注意序列化(到XML或JSON)循环引用的数量太多了,因为客户的产品中有一个客户的产品存在堆栈溢出异常。

+1正是我所想的,您可能还需要添加remove方法:)@SriramSakthivel。成对操作的每个方法。一个假设的包装类在不需要的情况下如何做您想要的事情ng是否要在该类的代码中手动添加关系?没有其他方法可以跟踪该关系。因此,唯一需要决定的是将添加的代码准确放置在何处。在这篇文章中,对于这个问题有一个优雅的答案,将代码多次放在方法中以便于重用,这是他们在编程时所教授的幼儿园,我真的不认为你需要从其他人那里听到这些才能这样做。至于更多的“工程”解决方案来做“它”,问题是你没有具体说明“它”是什么。在我看来,这个问题不能有意义地回答,因为它太笼统了。你自己对“有意义”的定义肯定是这样的。此外,侮辱那些指出如果你改进了问题,你会得到更好答案的人可能会有一些好处,但肯定不是我能看到的。请同时考虑到你得到的所有答案彼此都有很大的不同。这可能暗示了什么。谢谢,我真的很喜欢这种方法。你知道吗有一个显著的pe
public class Customer
{
  //other customer properties

  //field for the product list
  private List<Product> products = new List<Product>();

  //read-only property for outside access
  public IEnumerable<Product> Products
  {
    get { return products; }
  }

  //public method, open to the world
  public void BuyProduct(Product product)
  {
    products.Add(product);
    product.AddCustomer(this);
  }

  //public method, open to the world
  public void RemoveProduct(Product product)
  {
    products.Remove(product);
    product.RemoveCustomer(this);
  }        
}
customer1.BuyProduct(product1);