• NHibernate 联合主键(compositeid)


    转载地址:http://www.cnblogs.com/lyj/archive/2009/10/18/nh-wiki-compositeid.html

    概览

    这个系列是以博客形式整理关于NHibernate的Issues。记录一些零碎的小例子,通过零零碎碎的整理,可以巩固自己的知识和扩展我们的知识面。这些小例子也可以适当的在项目中呈现。

    这次看看联合主键(composite-id)。

    实例

    有时建模需要,需要把几个属性组合了一个标识符,就用到了联合主键(composite-id),我们使用它,就难免遇到了一些问题,比如如何映射,如何等同性比较,如何查询等操作。

    1.Domain

    这里定义一个Domain——CustomerValue,这个持久化类有两个属性:联合主键(composite-id)和Value。

    我们使用联合主键,首先需要定义联合主键的类型,同时这个类必须重载Equals()和GetHashCode()方法,来实现组合的标识符等同性判断。 例如下面的CustomerValue持久化类,其联合主键类型为CustomerValueId,就是Customer持久化类与int类型的复合形式,在CustomerValueId类中重载了Equals()和GetHashCode()方法。

    public class Customer
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }
    
    public class CustomerValue
    {
        public virtual CustomerValueId Id { get; set; }
        public virtual decimal Value { get; set; }
    }
    
    public class CustomerValueId : IEquatable<CustomerValueId>
    {
        private int? _requestedHashCode;
    
        public Customer Customer { get; set; }
        public int CustomKey { get; set; }
    
        public bool Equals(CustomerValueId other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            return Equals(other.Customer, Customer) && other.CustomKey == CustomKey;
        }
    
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            if (obj.GetType() != typeof(CustomerValueId))
            {
                return false;
            }
            return Equals((CustomerValueId)obj);
        }
    
        public override int GetHashCode()
        {
            if (!_requestedHashCode.HasValue)
            {
                unchecked
                {
                    _requestedHashCode =
                     ((Customer != null ? Customer.GetHashCode() : base.GetHashCode()) * 397) ^ CustomKey;
                }
            }
            return _requestedHashCode.Value;
        }
    }

    2.Mapping

    需要对两个Domain映射,这里注重理解下联合主键的映射,这里是把类的Customer属性和CustomerKey属性组合成为标识符属性。<key-many-to-one>节点用于映射子元素,一般都是Domain(多对一关系的);<key-property>节点用于映射属性。在这里我需要在<key-many-to-one>节点中设置not-found attribute来避免在运行时抛出异常,就是设置not-found="ignore"。

    <class name="Customer">
        <id name="Id">
            <generator class="hilo" />
        </id>
        <property name="Name" />
    </class>
    
    <class name="CustomerValue" >
        <composite-id name="Id" class="CustomerValueId">
            <key-many-to-one name="Customer" column="CustomerId" not-found="ignore" />
            <key-property name="CustomKey" />
        </composite-id>
        <property name="Value" />
    </class>

    3.Test

    做完了上面的步骤,测试一下,保存一个CustomerValue。查询验证下并删除。这个测试很简单,就不贴出SQL结果了。

    using (var session = OpenSession())
    {
        using (var tx = session.BeginTransaction())
        {
            var customer = new Customer { Name = "李永京" };
            session.Save(customer);
            var customerValue = new CustomerValue
                                    {
                                        Id = new CustomerValueId { Customer = customer, CustomKey = 20012 },
                                        Value = 1255.0m
                                    };
            session.Save(customerValue);
            tx.Commit();
        }
        using (var tx = session.BeginTransaction())
        {
            var customerValue = session.CreateQuery("from CustomerValue c where c.Value=:value")
                .SetDecimal("value", 1255.0m)
                .UniqueResult<CustomerValue>();
            session.Delete(customerValue); 
            session.Delete("from Customer");
            tx.Commit();
        }
    }
    
  • 相关阅读:
    每日日报24
    每日日报23
    每日日报22
    链路层:MAC 地址
    应用层:电子邮件
    应用层:HTTP 协议
    应用层:DNS 域名系统
    运输层:TCP 拥塞控制
    运输层:拥塞控制原理
    JAVA学习日记26-0731
  • 原文地址:https://www.cnblogs.com/smthts/p/2670223.html
Copyright © 2020-2023  润新知