Свободный составной ключ NHibernate с датами - PullRequest
3 голосов
/ 03 июня 2009

Я новичок в NHibernate и испытываю трудности с простой, но упрямой ошибкой.

В моей БД есть таблица (MSSQL2008), в которой составной ключ состоит из 2 столбцов даты.

Это будет период времени StartDate и EndDate, который является уникальным для целей моего решения.

Определение таблицы таково:

CREATE TABLE [dbo]. [CompositeKeyTab] ( [KeyCol1] [date] НЕ NULL, [KeyCol2] [date] НЕ NULL, [Значение] [десятичное] (18, 0) NULL, CONSTRAINT [PK_CompositeKeyTab] ПЕРВИЧНЫЙ КЛЮЧ КЛАСТЕР ( [KeyCol1] ASC, [KeyCol2] ASC ) С (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [ПЕРВИЧНЫЙ] ) НА [ПЕРВИЧНО]

В моей доменной модели у меня есть соответствующая сущность:

public class CompositeKeyEnt
{
    public virtual DateTime KeyCol1 { get; set; }
    public virtual DateTime KeyCol2 { get; set; }
    public virtual decimal Val { get; set; }

    public override bool Equals(object obj)
    {
        var compareTo = obj as FinancialDay;
        if (compareTo == null)
            return false;
        return this.GetHashCode() == compareTo.GetHashCode();
    }
    public override int GetHashCode()
    {
        return this.KeyCol1.GetHashCode() ^ this.KeyCol2.GetHashCode();
    }
}

и в моей картографической сборке карта:

public class CompositeKeyEntMap: ClassMap<CompositeKeyEnt>
{
    public CompositeKeyEntMap()
    {
        WithTable("CompositeKeyTab");
        UseCompositeId().WithKeyProperty(e => e.KeyCol1, "KeyCol1").WithKeyProperty(e => e.KeyCol2, "KeyCol2");
        Map(e => e.Val, "Value");
    }    
}

Все компилируется нормально. Но когда я пытаюсь сохранить экземпляр моего класса в БД (например, так)

        CompositeKeyEnt cke = new CompositeKeyEnt() { KeyCol1 = DateTime.Now.AddDays(1), KeyCol2=DateTime.Now.AddDays(1), Val = 2.2M };
        CompositeKeyEnt cke1 = new CompositeKeyEnt() { KeyCol1 = DateTime.Now, KeyCol2 = DateTime.Now, Val = 1.1M };
        Repository<CompositeKeyEnt> crep = new Repository<CompositeKeyEnt>();
        crep.SaveOrUpdate(cke);
        crep.SaveOrUpdate(cke1);

Я получаю:

"Неожиданное количество строк: 0; ожидаемое: 1"

Когда в сеансе вызывается Flush ().

    public virtual T SaveOrUpdate(T entity)
    {
        using (var context = Session)
        {
            context.SaveOrUpdate(entity);
            context.Flush(); //Exception raised here!!!
        }
        return entity;
    }

Что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 11 июля 2009

Я думаю, что проблема в том, что NHibernate не знает, что является несохраненным значением для вашего составного ключа, поэтому он пытается выпустить обновление вместо вставки, когда вы вызываете SaveOrUpdate (). Я не вижу никакой возможности для вас иметь действительное несохраненное значение для этого класса, поэтому я предлагаю вам изменить ваш репозиторий, чтобы он реализовал Save () и Update () отдельно и вызвал соответствующий метод.

0 голосов
/ 15 июня 2009

У меня возникла та же проблема, я обнаружил, что если вы добавляете новый элемент в базу данных, вам нужно вызвать Save (), а если вы обновляете элемент, то вам нужно вызвать Update ().

По какой-то причине, похоже, ошибка при вызове SaveOrUpdate ().

Надеюсь, это поможет

...