Monday, January 3, 2011

Refresh primary key column after insert using Domain Services in RIA services on Entity framework

Situation: 2 tables where a primary key in one table is foreign key in another table.
E.g. table Agendum {Id - identity column and primary key, heading, description}
table Take {Id - identity column and primary key, heading, description, AgendumId - foreign key}

Issue I was facing: I wanted to insert Agendum entity into Agendum table, retrieve the identity column value so that when I insert Take entity into Take table, I can pass the AgendumID which is the identity column of Agendum table.

I am using: Domain services (RIA services) on Entity framework. This is a silverlight app.

Wrong way of doing, which I was trying to do:

            //First insert into Agenda table and get the agenda id back
            Agendum _agenda = new Agendum();
            _agenda.Heading = tbAgendaTitle.Text;
            _agenda.SourceUri = tbAgendaSource.Text;
            m_domainCtx.Agendums.Add(_agenda);
            m_domainCtx.SubmitChanges(Callback, null);
 
            Take _take = new Take();
            _take.Heading = tbTakeTitle.Text;
            _take.Description = tbTakeDesc.Text;
            _take.AgendaId = _agenda.Id;
 
            m_domainCtx.Takes.Add(_take);
            m_domainCtx.SubmitChanges(Callback, null);
As I was trying to call SubmitChanges twice, I was getting the error: 
A SubmitChanges operation is already in progress on this DomainContext.

After reading the article on the blog: http://blogs.msdn.com/b/adonet/archive/2008/03/26/stored-procedure-mapping.aspx, I figured the proper way of doing it. 

Proper way of doing: 
            //First insert into Agenda table and get the agenda id back
            Agendum _agenda = new Agendum();
            _agenda.Heading = tbAgendaTitle.Text;
            _agenda.SourceUri = tbAgendaSource.Text;
            m_domainCtx.Agendums.Add(_agenda);
 
            Take _take = new Take();
            _take.Heading = tbTakeTitle.Text;
            _take.Description = tbTakeDesc.Text;
            _take.Agendum = _agenda;
 
            m_domainCtx.Takes.Add(_take);
            m_domainCtx.SubmitChanges(AdminPostCallback, null);
So, you dont have to retrieve the primary key and assign it explicitly. The associations are known to the Domain Service. Hence just assigning the entity will take care of it. 
Hope it helps.

1 comment:

Anonymous said...

Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with more information......


domain service