我在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的情况下防止数据重复。
当实现像使用Server的制造商这样的引用时,我的数据模型将包含一个唯一的ID字段,然后我的Product类将被一个ManufacturerID污染。我设想使用像db4o这样的对象数据库可以减少关系数据库和对象之间的阻抗不匹配,但是如果没有it,就无法在编辑对象时区分一个对象和另一个对象。
是否有一种优雅的方式在产品之间共享制造商而不复制数据?还是应该只使用关系数据库呢?
发布于 2011-03-14 22:05:34
您可以在配置中向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-14 22:04:39
最基本的事情。db4o通过他们的对象-身份管理对象。当您再次存储同一个对象实例时,db4o将在数据库中更新该对象。这同样适用于参考资料。当两个不同的对象引用同一个对象时,它们实际上将引用数据库中的同一个对象。在您的示例中:当两个不同的产品引用同一个制造商-实例时,它们也将引用数据库中的同一个制造商。这是通过在后台有一个表来实现的,跟踪对象就是这样做的.
现在,这种方法有了问题。一旦您序列化对象(web应用程序、web服务等)或关闭对象容器,db4o就会忘记内存中的哪个对象属于哪个对象。然后,它不再识别一个现有的对象,只是存储作为一个新的对象。这意味着您永远不应该用不同的对象容器实例加载和存储对象。而且你可能需要识别对象的ID。例如,识别跨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);发布于 2012-09-28 11:59:46
db4o确实为存储的每个对象维护一个唯一的内部ID。
检查以下链接:concept.htm
ids.htm
https://stackoverflow.com/questions/5304097
复制相似问题