1

我围绕 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,在编辑对象时就无法区分一个对象和另一个对象。

有没有一种优雅的方法可以在不复制数据的情况下在产品之间共享制造商?还是我应该只使用关系数据库?

4

3 回答 3

1

先说基本的东西。db4o 通过对象身份管理对象。当您再次存储相同的对象实例时,db4o 将更新数据库中的该对象。这同样适用于引用。当两个不同的对象引用同一个对象时,它们实际上将引用数据库中的同一个对象。在您的示例中:当两个不同的产品引用同一个制造商实例时,它们也将引用数据库中的同一个制造商。这是通过在后台有一个跟踪对象的表来实现的。

现在这种方法有问题。一旦您序列化对象(Web 应用程序、Web 服务等)或关闭对象容器,db4o 就会忘记内存中的哪个对象属于哪个对象。然后它不再识别现有对象,只是将其存储为新对象。这意味着您永远不应加载和存储具有不同对象容器实例的对象。并且您可能需要ID 来识别对象。例如,跨网络请求识别对象。一个简单的解决方案是使用 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);
于 2011-03-14T22:04:39.947 回答
1

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

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

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

于 2011-03-14T22:05:34.050 回答