2016-04-01 1 views
0

Я не могу заставить это работать. У меня есть EntityFramework 6 с бэкэнд PostgreSQL.Как обновить объект после SaveChanges, чтобы получить назначение последовательности бэкэнд?

Бэкэнд PostgreSQL (9.5) использует триггер getnextticketnumber для последовательного назначения целых чисел новым записям по мере их добавления. После того, как EntityFramework создаст новую запись в базе данных с помощью SaveChanges(), идентификатор записи на новом объекте будет правильно обновлен. Тем не менее, ticketno объекта остается нулевым, несмотря на то, что проверка соответствующей записи в базе данных имеет присвоенный номер нулевого номера билета. Таким образом, похоже, что запись PostgreSQL будет правильно сделана, но объект будет продолжать показывать ее как null. То есть, это дает неправильные результаты:

// read back ticket to get the ticketno from Postgresql. 
    ticket = ctx.established_patients.Where(t => t.recid == ticket.recid).First(); 

Вот сопроводительная документация. TIA за любую идею о том, почему это не работает и/или как заставить ее работать!

established_patients ticket = (from e in ctx.established_patients 
         where e.patient_recid == estpt.recid 
         select e) 
         .SingleOrDefault(); 

       if (ticket == null) 
       { 
        // create a ticket for an established patient 
        ticket = new established_patients 
        { 
         modified = DateTime.Now, 
         patient_recid = estpt.recid, 
         ticketno = null 
        }; 
        ctx.established_patients.Add(ticket); 
        ctx.SaveChanges(); 

        // read back ticket to get the ticketno from Postgresql. 
        ticket = ctx.established_patients.Where(t => t.recid == ticket.recid).First(); 
       } 
       ticketno = (int)ticket.ticketno; 
       return ticketno; 

PostgreSQL (9,5) триггер:

CREATE OR REPLACE FUNCTION getnextticketnumber() 
    RETURNS trigger AS 
$BODY$ 
BEGIN 
    -- Check for null ticketnumber 
    IF NEW.ticketno is null THEN 
    New.ticketno := nextval('patient_ticket_number_seq'); 
    END IF; 
    RETURN NEW; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION getnextticketnumber() 
    OWNER TO postgres; 

Спусковой помещается на этой таблице:

CREATE TABLE established_patients 
(
    recid serial NOT NULL, 
    ticketno integer, 
    patient_recid integer NOT NULL, 
    modified timestamp without time zone DEFAULT now(), 
    CONSTRAINT established_patients_pk PRIMARY KEY (recid), 
    CONSTRAINT established_patients_patient_fk FOREIGN KEY (patient_recid) 
     REFERENCES patients (recid) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT established_patients_unqiue UNIQUE (patient_recid) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE established_patients 
    OWNER TO postgres; 

-- Trigger: new_ticket_number on established_patients 

-- DROP TRIGGER new_ticket_number ON established_patients; 

CREATE TRIGGER new_ticket_number 
    BEFORE INSERT 
    ON established_patients 
    FOR EACH ROW 
    EXECUTE PROCEDURE getnextticketnumber(); 

-- Trigger: update_modified on established_patients 

-- DROP TRIGGER update_modified ON established_patients; 

CREATE TRIGGER update_modified 
    BEFORE UPDATE 
    ON established_patients 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_modified(); 
+0

Является ticketno поля автоматического приращения? Зачем вам нужен триггер? – jpgrassi

+0

@jpgrassi У меня есть несколько таблиц, каждая из которых описывает разные наборы данных. Затем каждая из этих таблиц связана с одной таблицей. Билетно должен быть уникальным для базы данных, а не только для таблицы. :) –

ответ

1

Я думаю, что вы не карту объект должным образом. Если вам нужно, чтобы СУБД обрабатывала ее (и EF читает ее), вам нужно отметить ее как StoreGeneratedPattern.Computed.
Если вы этого не сделали, у вас также может возникнуть проблема с тем, что EF пытается записать его во время обновлений.

Для получения дополнительной информации https://msdn.microsoft.com/en-us/library/dd296755(v=vs.90).aspx

+0

Вот и все! Спасибо за совет. Я также нашел, что это работает: ctx.Entry (ticket) .Reload(); но это казалось ненужным дополнительным шагом. –

Смежные вопросы