维护类之间的双向关系 [英] Maintaining a two way relationship between classes

查看:152
本文介绍了维护类之间的双向关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是很常见的,尤其是在一个ORM的应用,有类之间的双向映射。像这样的:

It is pretty common, especially in applications with an ORM, to have a two way mapping between classes. Like this:

public class Product
{
    private List<Price> HistoricPrices { get; private set;}
}

public class Price
{
    private Product Product { get; set; }
}

有维护代码这种关系的一个公认的方式?所以,当我添加一个价格产品的产品属性,都会自动设置?

Is there an accepted way of maintaining this relationship in code? So that when I add a price to a product the Product property gets set automatically?

在理想情况下,我在寻找一个容易的可重用的解决方案。这似乎是错误的有东西添加到一个集合,然后手动设置相反的关系。

Ideally I am looking for an easily reusable solution. It seems wrong to have to add something to a collection and then set the opposite relations manually.

请注意,这不是一个关于如何产品和价格的问题范本,它是如何将一个2路关系模型的问题。 。有很多的地方,这是完全合理的情况下

Please note that this is not a question about how to model products and prices, It is a question of how to model a 2 way relationship. There are plenty of situations where this is perfectly reasonable.

推荐答案

首先,我认为,比如你现在是混乱 - 这是罕见像一个价格被建模为一个对象或具有参照,将有一个价格的实体。但我认为这个问题是合法的 - 在世界ORM这有时被称为图形一致性。据我所知,没有的有一个的明确的方法来解决这个问题,有几种方法。

First, I think the example your present is confusing - it's uncommon for something like a Price to be modeled as an object or to have reference to the entities that would have a price. But I think the question is legitimate - in the ORM world this is sometimes referred to as graph consistency. To my knowledge there isn't one definitive way to tackle this problem, there are several ways.

让我们通过改变例如略有启动:

Let's start by changing the example slightly:

public class Product
{
    private Manufacturer Manufacturer { get; private set;}
}

public class Manufacturer
{
    private List<Product> Products { get; set; }
}



所以,每个产品都有一个制造商,每个制造商可能会名单产品。与模型的挑战是,如果产品类和生产者类保持断开引用彼此,更新可以无效其他

So every Product has one Manufacturer, and each Manufacturer could have a list of products. The challenge with the model is that if the Product class and Manufacturer class maintain disconnected references to one another, updating one can invalidate the other.

有多种方法来解决这个问题:

There are several ways to address this issue:


  1. 消除循环引用。这解决了问题,但使对象模型较少表现,更难使用。

  1. Eliminate the circular reference. This solves the problem but makes the object model less expressive and harder to use.

更​​改代码,以便在制造商的产品和产品列表制造商的参考是的自反的。换句话说,更改一个影响其他。这通常需要一些代码setter和收集拦截变化和的反映的他们到另一个。

Change the code so that the Manufacturer reference in Product and Products list in Manufacturer are reflexive. In other words, changing one affects the other. This generally requires some code the setter and the collection to intercept changes and reflect them into one another.

管理来讲一个属性的另一个。因此,而不是存储产品中的制造商参考,您可以通过搜索通过全部制造商计算,直到你找到拥有你的人。相反,你可以保持在产品类制造商的引用,并动态地构建产品的列表。在这种方法,通常将使得关系只读的一侧。这,顺便说一句,是标准的关系型数据库的方法 - 实体通过它在一个地方管理的外键相互引用

Manage one property in terms of the other. So, rather than storing a reference to a manufacturer within Product, you compute it by search through all Manufacturers until you find the one that owns you. Conversely, you could keep a reference to the Manufacturer in the Product class and build the list of Products dynamically. In this approach, you would generally make one side of the relationship read-only. This, by the way, is the standard relational database approach - entities refer to each other through a foreign key which is managed in one place.

外部化的关系。从的两个的类和一个单独的对象进行管理(通常称为ORM数据上下文)。当产品要回到它的制造商,它要求在DataContext。当制造商想要回产品列表确实是一样的。在内部,也有实现数据的背景下,一组双向词典的许多方面并不少见。

Externalize the relationship from both classes and manage it in a separate object (often called a data context in ORM). When Product wants to return its manufacturer it asks the DataContext. When the Manufacturer want to return a list of Products it does the same. Internally, there are many ways to implement a data context, a set of bi-directional dictionaries is not uncommon.

最后,我会提到,你应该考虑使用ORM工具(如NHibernate的或CSLA),可以帮助您管理图形一致性。这通常是不正确容易解决的问题 - 一旦你开始探索情况下,像许多一对多的关系,一到一对一的关系,和对象的延迟加载它可以很容易变得很复杂。你是使用现有的库或产品,而不是你自己发明的一种机制,更好地

Finally, I will mention, that you should consider using an ORM tool (like NHibernate or CSLA) that can help you manage graph consistency. This is generally not an easy problem to solve correctly - and it can easily become very complicated once you start exploring cases like many-to-many relationships, one-to-one relationships, and lazy loading of objects. You are better of using an existing library or product, rather than inventing a mechanism of your own.

下面是一些的 是讲的双向关联NHibernate的的你。可能会发现有用的。

Here are some links that talk about bidirectional associations in NHibernate that you may find useful.

下面是一个使用方法#3直接管理的关系自己的代码示例 - 通常是最简单的。注意,只有一个的关系的侧面是可编辑​​的(在这种情况下,生产商) - 外部消费者不能直接设置一个产品的制造商

Here's a code example of managing the relationships directly yourself using method #3 - which is typically the simplest. Note that only one side of the relationship is editable (in this case, the Manufacturer) - external consumers cannot directly set the Manufacturer of a Product.

public class Product
{
    private Manufacturer m_manufacturer;

    private Manufacturer Manufacturer
    {
      get { return m_manufacturer;}
      internal set { m_manufacturer = value; }
    }
}

public class Manufacturer
{
    private List<Product> m_Products = new List<Product>();

    public IEnumerable<Product> Products { get { return m_Products.AsReadOnly(); } }

    public void AddProduct( Product p )
    {
      if( !m_Products.Contains( p ) )
      {
        m_Products.Add( p );
        p.Manufacturer = this;
      }
    }

    public void RemoveProduct( Product p )
    {
      m_Products.Remove( p );
      p.Manufacturer = null;
    }
}

这篇关于维护类之间的双向关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆