FK-PK synchronization

Posts   
 
    
Skeeterbug
User
Posts: 165
Joined: 21-May-2004
# Posted on: 16-Feb-2006 19:22:43   

Ok let me explain my DB schema a bit here. I have two tables that I am working with, Process, and ProcessPredecessor

Here is how Process looks:

ProcessId ProcessName ... etc

This is how ProcessPredecessor looks:

ProcessPredecessorId ProcessId (original process) PredecessorId (predecessor process)

LLBLGen created the ProcessPredecessor entity, and it has these two fields, Process and Process_. Also, in the process entity, we have ProcessPredecessor entity collection (Everything seems OK at this point).

Process field in ProcessPredecessor is mapped by ProcessId FK Process_ field in ProcessPredecessor is mapped by PredecessorId FK

I have two sperate programs that I am working with. One program converts a Microsft Project XML file and creates my process hiararchy. The other program is meant to persist it. In Microsoft Project, the Predecessors are created by referencing their UID. So each process is giving the UID from project. In that conversation, I have a method which assigns the Predecessor, something like this:


ProcessPredecessor pd = new ProcessPredecessor();
pd.ProcessId = procId;
pd.PredecessorId = predId;
return pd;

pd is then added to the process.ProcessPredecessor collection (nothing unusual about this).

First problem: After the process entities are constructed, predecessor.Process is not null, but predecessor.Process_ is null (even though BOTH FK's were set).

Second problem: When trying to recursively save the process entities' ProcessPredecessor collection, it throws a FK_Constraint error. I took off the FK constraint in the DB, and it appears the the first foreign key is being synchronized, and the second (predecessorId) did not updated correctly.

Let me know if anything needs further explaination.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 17-Feb-2006 02:53:33   

Can you show the code for these 3 sections? Also what are the types of the IDs?

  • pd is then added to the process.ProcessPredecessor collection (nothing unusual about this).

  • First problem: After the process entities are constructed, predecessor.Process is not null, but predecessor.Process_ is null (even though BOTH FK's were set).

  • Second problem: When trying to recursively save the process entities' ProcessPredecessor collection, it throws a FK_Constraint error. I took off the FK constraint in the DB, and it appears the the first foreign key is being synchronized, and the second (predecessorId) did not updated correctly.

Skeeterbug
User
Posts: 165
Joined: 21-May-2004
# Posted on: 17-Feb-2006 18:06:15   

Ok, The ID's are int.

Here is the first part:


...

XmlNodeList l = doc.GetElementsByTagName("PredecessorLink");
foreach(XmlNode n in l)
{
    procToAdd.ProcessPredecessor.Add(GetPred(procToAdd.ProcessId, System.Convert.ToInt32(n.ChildNodes[0].InnerXml)));
}

collection.Add(procToAdd);

GetPred function:


private ProcessPredecessorEntity GetPred(int procId, int predId)
{
    ProcessPredecessorEntity pp = new ProcessPredecessorEntity();
    pp.ProcessId = procId;
    pp.PredecessorId = predId;
    return pp;
}

The code in the second project:


...

//Loop through all the processes
for(int xx=0;xx<coll.Count;xx++)
{
    ProcessEntity proc = (ProcessEntity)coll[xx];
    proc.IsNew = true;
    proc.ProjectId = project.ProjectId;
    proc.UserId = id;
    TimeSpan span = proc.TargetDate - proc.StartDate;
    proc.Duration = (int)span.TotalDays + 1;
    proc.ProcessStatusId = 1;
    proc.CompletedValue =0;
    proc.EndDate = proc.TargetDate;
    proc.CreatedOn = DateTime.Now;
    proc.ModifiedOn = DateTime.Now;
    for(int yy=0;yy<proc.ProcessPredecessor.Count;yy++)
    {
        ProcessPredecessorEntity pd = (ProcessPredecessorEntity)proc.ProcessPredecessor[yy];
        pd.ModifiedOn = DateTime.Now;
        pd.CreatedOn = DateTime.Now;
    }

}

//Save all the Processes
adapter.SaveEntityCollection(coll,true,true);

As you can see in the GetPred function, I am setting both the foreign keys. This application also has code to show the Predecessor in a grid (this works ok). The second app persists it, that is where it's failing.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 18-Feb-2006 03:32:50   

I believe that the reason you see the process, but not process_ is because the ProcessPredecessor is being added to the ProcessPredecessor collection of process and not process_. So that relation and data exists without having to perform a fetch from the database. I'm not sure why the pp.PredecessorId is not being saved correctly. When you debug this section

for(int yy=0;yy<proc.ProcessPredecessor.Count;yy++)
    {
        ProcessPredecessorEntity pd = (ProcessPredecessorEntity)proc.ProcessPredecessor[yy];
        pd.ModifiedOn = DateTime.Now;
        pd.CreatedOn = DateTime.Now;
    }

does proc.PredecessorId have a value in it? Is that field marked as an entity or read-only in the designer?

Skeeterbug
User
Posts: 165
Joined: 21-May-2004
# Posted on: 20-Feb-2006 22:29:10   

bclubb wrote:

I believe that the reason you see the process, but not process_ is because the ProcessPredecessor is being added to the ProcessPredecessor collection of process and not process_. So that relation and data exists without having to perform a fetch from the database. I'm not sure why the pp.PredecessorId is not being saved correctly. When you debug this section

for(int yy=0;yy<proc.ProcessPredecessor.Count;yy++)
    {
        ProcessPredecessorEntity pd = (ProcessPredecessorEntity)proc.ProcessPredecessor[yy];
        pd.ModifiedOn = DateTime.Now;
        pd.CreatedOn = DateTime.Now;
    }

does proc.PredecessorId have a value in it? Is that field marked as an entity or read-only in the designer?

Yes, when I remove the FK constraint in the table it is only updating the ProcessId and not PredecessorId, the value is still there (it's incorrect). With the FK constraint on, it will fail to save obviously because the PredecessorId is old and points to nothing. No, the fields aren't read only in the designer.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 21-Feb-2006 07:10:25   

Second problem: When trying to recursively save the process entities' ProcessPredecessor collection, it throws a FK_Constraint error. I took off the FK constraint in the DB, and it appears the the first foreign key is being synchronized, and the second (predecessorId) did not updated correctly

That's because the ProcessPredecessor Entity is pointing to a Process that's not yet saved from the collection of Processes. Please note: That MS Project permits to have a Predeccesor which comes later in the Hierarchy, so a predecessor of a Process can come after the Process in the XML File

Please refer to the LLBLGen documentation and read the How do I add an entity A to an entity B's collection of A's if A and B have an m:n relation ? under "Best Practices -> How Do I ... ?"

Also try to use a UnitOfWork for saving your Process Collection.

Skeeterbug
User
Posts: 165
Joined: 21-May-2004
# Posted on: 21-Feb-2006 18:30:30   

EDIT*

Ok I got it working. Instead of assigning the ID's, I am now assigning to references of a ProcessEntity object in my collection. Maybe this could be noted in the documentation so other people don't run into this problem? Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Feb-2006 07:12:29   

I think that was noted in the "Best Practices -> How Do I ... ?" as mentioned before.