代码之家  ›  专栏  ›  技术社区  ›  R. Martinho Fernandes

没有空构造函数和setter的nhibernate映射

  •  3
  • R. Martinho Fernandes  · 技术社区  · 15 年前

    我正在测试将nhiberiate用于完全不知道它的域是多么困难,并且不打算去适应任何限制。

    在我在网上发现的许多例子中,被映射的域是贫血域的另一个例子,在这个领域中,对象远不是简单的数据持有者。当然,这使得映射变得简单,而且可能会吸引以数据为中心的人/情况,但我不喜欢听到我头脑中的声音说“C也有结构,你知道吗?”“类不仅仅是花哨的名称空间,你知道吗?”或者“为什么不使用创建表?”.

    但回到了NHIBERNATE。nHibernate强制我将属性设置为虚拟的,以便能够代理它们进行延迟加载。这是我不介意的,因为我可能也需要它们作为一些AOP的虚拟对象。 我不满意的限制是需要一个空的构造函数和设置器/属性。我希望在有效状态下创建我的实体,大多数情况下这意味着没有空的构造函数。 出于通常的原因,我也不想公开集合属性的setter。哦,以及不应该直接更改的属性的setter。

    考虑域模型中的这个简化和人为聚合:

    public class ShoppingCartItem
    {
        private readonly Product product;
    
        public ShoppingCartItem(Product product, int quantity)
        {
            if(quantity <= 0)
                throw new ArgumentOutOfRangeException("quantity");
            this.product = product;
            this.quantity = quantity;
        }
        public virtual Product Product
        {
            get { return product; }
        }
        private int quantity;
        public virtual int Quantity
        {
            get { return quantity; }
            set
            {
                if(value <= 0)
                    throw new ArgumentOutOfRangeException("value");
                quantity = value;
        }
    
        public virtual Money TotalPrice
        {
            get { return product.Price * quantity; }
        }
    }
    
    public class ShoppingCart : Entity
    {
        private readonly IDictionary<Product, ShoppingCartItem> items =
            new Dictionary<Product, ShoppingCartItem>();
        private readonly ISet<DiscountCoupon> discountCoupons =
            new HashSet<DiscountCoupon>();
    
        public virtual IEnumerable<ShoppingCartItem> Items
        {
            get { return items.Values; }
        }
    
        public virtual IEnumerable<DiscountCoupon> DiscountCoupons
        {
            get { return discountCoupons; }
        }
    
        public virtual void AddProduct(Product product)
        {
            ShoppingCartItem item;
            if(items.TryGetValue(product, out item))
                item.Quantity++;
            else
                items.Add(product, new ShoppingCartItem(product, 1));
        }
    
        public virtual void RemoveProduct(Product product)
        {
            ShoppingCartItem item;
            if(!items.TryGetValue(product, out item))
                throw new ArgumentException("product");
    
            if(item.Quantity == 1)
                items.Remove(product);
            else
                item.Quantity--;
        }
    
        public virtual int AddDiscountCoupon(DiscountCoupon coupon)
        {
            discountCoupons.Add(coupon);
        }
    
        public virtual int RemoveDiscountCoupon(DiscountCoupon coupon)
        {
            discountCoupons.Remove(coupon);
        }
    
        public virtual Money CalculatePrice()
        {
            // Missing complex discount logic
            return items.Values.Sum(item => item.TotalPrice);
        }
    }
    

    大多数属性没有setter,也看不到空构造函数。集合不是直接干预的,而是通过专门的方法。我可以利用NHibernate的可扩展性来映射这个吗?还是我想再敲一次螺丝?还是两者兼而有之?

    2 回复  |  直到 14 年前
        1
  •  8
  •   Jaguar    15 年前

    好吧,你可以将私有/内部/受保护的setter放在属性/集合上,nhibernate会正确地加载它们(第4.1.1章)

    构造函数 但您没有义务公开(第4.1.2章)

    最新章节参考 http://sourceforge.net/projects/nhibernate/files/NHibernate/2.1.2GA/NHibernate-2.1.2.GA-reference.zip/download

        2
  •  4
  •   Shane Courtrille    15 年前

    首先,您可以将空构造函数设为私有的,这样其他人就无法访问它。NH仍然能够做到。

    第二关NH可以访问你的财产,无论你想要。

    access=“backfield”用于公共虚拟产品get;private set;

    access=“field.pascalcase-m-underline”用于m_产品

    access=“field.pascalcase underline”用于\u产品

    还有其他的访问策略,如果需要的话,我相信你甚至可以创建自己的访问策略。