db4o阻抗不匹配

时间:2011-03-14 20:27:52

标签: db4o duplication

我在db4o数据库周围构建了一个很好的存储库层来存储Product个对象,这些对象与一对多关系中的Manufacturer个对象有关,即:

public class Manufacturer
{
    public string Name { get; set; }
}

public class Product // simplified
{
    public string Name { get; set; }
    Manufacturer Manufacturer { get; set; }
}

到目前为止,我真的很喜欢db4o。我遇到的问题是在不使用ID的情况下阻止数据重复。

当使用SQL Server实现像制造商这样的引用时,我的数据模型将包含一个唯一的ID字段,反过来,我的Product类将被 ManufacturerID 弄脏。我想像使用像db4o这样的对象数据库可以减少关系数据库和对象之间的阻抗不匹配,但是没有ID,编辑它时就没有办法告诉另一个对象。

在没有重复数据的情况下,是否有一种优雅的方式在产品之间共享制造商?或者我应该只使用关系数据库?

3 个答案:

答案 0 :(得分:1)

首先是基本的事情。 db4o按their object-identity管理对象。再次存储同一个对象实例时,db4o将更新数据库中的该对象。这同样适用于参考文献。当两个不同的对象引用同一个对象时,它们实际上会引用数据库中的同一个对象。在您的示例中:当两个不同的产品引用相同的Manufacturer-instance时,它们也将引用数据库中的同一制造商。这是通过在背景中设置keeps track of the objects的桌子来实现的。

现在这种方法存在问题。只要序列化对象(Web应用程序,Web服务等)或关闭对象容器,db4o就会忘记内存中的哪个对象属于哪个对象。然后它不再识别现有对象,只是将存储作为新对象。这意味着您永远不应该使用不同的对象容器实例加载和存储对象。你可能需要IDs to recognizes objects。例如,跨Web请求识别对象。一个简单的解决方案是使用Guids为对象提供唯一的id。

回到你的问题。要在产品之间共享制造商,您只需将其指向同一制造商。像这样:

Product newShinyProduct = new Product(); // the new thing
// Get a existing product or manufacturerer, doesn't matter
Product oldProduct = (from p in container.AsQueryable<Product>()
                     where p.Name == "Get a product"
                     select p).First();

// now just assigne the existing manufacturer to the new product
// this product will now refer to the same manufacturer
// and db4o will store this that way. The manufacturer isn't doublicated.
newShinyProduct.Manufacturer = oldProduct.Manufacturer;
// store the new product in the database.
container.Store(newShinyProduct);

答案 1 :(得分:1)

您可以在配置中为db4o添加唯一索引。

configuration.Common.ObjectClass(typeof (Manufacturer)).ObjectField("<Name>k__BackingField").Indexed(true);
configuration.Add(new UniqueFieldValueConstraint(typeof(Manufacturer), "<Name>k__BackingField"));

这样,您的数据库中不可能有两个具有相同名称的不同Manufacturer对象。字段名称必须是“k__BackingField”,因为您使用的是自动属性。当然,您可以添加整数ID,并以相同的方式对其进行索引。

答案 2 :(得分:0)