在对象模型中定义关系的最佳方法?

时间:2013-01-11 09:56:03

标签: c# database database-design object-model

构建将object model映射到数据库表的classes时,如何指定与其他实体的关系?

示例:

Category
----------------------
CategoryId  INT     PK
Name        VARCHAR
Description VARCHAR

Product
----------------------
ProductId   INT     PK
CategoryId  INT     FK
Name        VARCHAR
UnitPrice   DECIMAL
UnitInStock INT


class Category 
{
     public int CategoryId { get; set; }
     public string Name { get; set; }
     public List<Product> Products { get; set; } //for navigation only
}

class Product
{
     public int ProductId { get; set; }
     public string Name { get; set; }
     public decimal UnitPrice { get; set; }
     public int UnitInStock { get; set; }
}

定义与其他实体的关系的最佳方法是什么?

class Product
{
     //...
     public Category Category;
}

class Product
{
     //...
     public int CategoryId;
}

或两者兼而有之? (一个用于数据库绑定(int CategoryId)一个用于导航(Category Category

class Product
{
     //...
     public int CategoryId;
     public Category Category;
}

3 个答案:

答案 0 :(得分:1)

这实际上取决于你的模型在关系方面的需求。通过将Category的任何类型的引用添加到您的Product中,您将在模型级别创建双向关系。从数据完整性的角度来看,这在数据库级别可能是必要的,但这并不意味着您的模型必须遵循,这样做并不总是有意义。

在我看来,Product不应该对Category有所了解,因为它没有必要。 Product可以独立存在而不与Category相关联。但是,如果您认为Product 了解它Category,那么请务必添加该属性。

  

Id属性与导航属性

这再次取决于您的要求。通常,使用导航属性是未来的证据,因为ID属性无论如何都会归结为其中的一部分。但是,当你真正需要的只是ID时,你可能会增加额外的开销来拉下整个对象。

答案 1 :(得分:0)

这取决于你想要达到的目标。如果需要backnavigation,请将主类本身添加为变量;但如果您不需要(或者如果您不需要),您只需添加标识符即可。

但是,我认为您应该选择其中一种方法并实施它。如果您尝试使用这两种方法,可能会导致问题。例如,假设在某些类中,您已将主类添加为backnavigation属性;如果你在某些情况下不需要怎么办?您将进行一些不必要的数据库查询,或者在某些情况下您将获得空值。

答案 2 :(得分:0)

我可以告诉你下面的代码。我使用它来保持实体之间的关系(数据实例与数据库的对象重新支持,即消费者,书籍)。它允许在第一次引用相关对象时读取内容。

public class EntityHandler<T, V>
        where T : Entity<V>, new()
        where V : DataObject
    {
        private long myDataObjectID;
        private T myEntityObject;
        public delegate Entity<V> GetEntityObject(long oid);

        private GetEntityObject GetEntityObjectFunction;

        private Entity<V> HandledEntity
        {
            set
            {
                if (myEntityObject == null)
                {
                    myEntityObject = (T)value;
                }
            }
            get { return myEntityObject; }
        }

        public EntityHandler(GetEntityObject extCntrGetBO, long oid)
        {
            myDataObjectID = oid;
            GetEntityObjectFunction = extCntrGetBO;
        }

        public T o
        {
            get
            {
                if (myEntityObject == null)
                {
                    myEntityObject = (T)GetEntityObjectFunction(myDataObjectID);
                }
                return myEntityObject;
            }
        }

        public long ID
        {
            get { return myDataObjectID; }
            set
            {
                myDataObjectID = value;
                myEntityObject = null;
            }
        }
    }