New Posts New Posts RSS Feed: Getting state of many to many relation
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Getting state of many to many relation

 Post Reply Post Reply
Author
rhaney View Drop Down
Newbie
Newbie


Joined: 06-Jul-2010
Location: Orange, CA
Posts: 12
Post Options Post Options   Quote rhaney Quote  Post ReplyReply Direct Link To This Post Topic: Getting state of many to many relation
    Posted: 06-Jul-2010 at 3:53pm

I have two entities, Group and Person, that are joined together in a many-to-many relationship.  When my UI first loads, I have present a list of groups.  When the user selects a group, I present the list of current people in that group.  

In my UI, if the user accidentally removes a person from a group and re-adds the person to the same group and tries to save, they get a FK violation error.
 
What I haven't been able to figure out to do is detect if the Person instance is pending removal from the group.  If I can detect and rollback the delete, I should be OK.
 
Ideally, I just add the person to the group again, and DevForce figures out that the relation already exists.
 
I thought about creating an intermediate entity that joins the Group and Person, but that just seems a kludge when I don't have additional properties.
 
Thoughts?
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 07-Jul-2010 at 3:08pm
I think this may be the result of something your UI is doing or not doing.

I tried the following:


    public void BasicQuerySyntaxQuery() {
      _em1.ExecuteQueryAsync(_em1.Employees.Where(c => c.Country == "USA"), GotEmployees, null);
    }

    private void GotEmployees(EntityQueryOperation<Employee> args) {
      _currentEmployee = args.Results.FirstOrDefault();
      _currentEmployee.Territories.PendingEntityListResolved += new EventHandler<PendingEntityListResolvedArgs<Territory>>(Territories_PendingEntityListResolved);
    }

    void Territories_PendingEntityListResolved(object sender, PendingEntityListResolvedEventArgs<Territory> e) {
      Territory aTerritory = e.ResolvedEntities[0];
      _currentEmployee.Territories.Remove(aTerritory);
      _currentEmployee.Territories.Add(aTerritory);
    }



If I throw code in there to output results ...


    public void BasicQuerySyntaxQuery() {
      _localOutput.Append(String.Format("[{0}] Started...\n", _nameBasicQuerySyntaxQuery));
      Utility.ResetEntityManager(_em1);

      _em1.ExecuteQueryAsync(_em1.Employees.Where(c => c.Country == "USA"), GotEmployees, null);
    }

    private void GotEmployees(EntityQueryOperation<Employee> args) {
      _localOutput.Append(string.Format("[{0}] Retrieved {1} customers\n",
        _nameBasicQuerySyntaxQuery, args.Results.Count()));

      _currentEmployee = args.Results.FirstOrDefault();

      _currentEmployee.Territories.PendingEntityListResolved += new EventHandler<PendingEntityListResolvedEventArgs<Territory>>(Territories_PendingEntityListResolved);
      Order newOrder = new Order();

      Utility.FlushOutputBuffer(_localOutput, _resultsReporter);
    }

    void Territories_PendingEntityListResolved(object sender, PendingEntityListResolvedEventArgs<Territory> e) {
      _localOutput.Append(string.Format("[{0}] Retrieved {1} related territories for Employee {2}\n",
        _nameBasicQuerySyntaxQuery, e.ResolvedEntities.Count, _currentEmployee.LastName));

      Territory aTerritory = e.ResolvedEntities[0];
      _currentEmployee.Territories.Remove(aTerritory);
      _localOutput.Append(string.Format("[{0}] No. of territories after removing one: {1}\n",
        _nameBasicQuerySyntaxQuery, _currentEmployee.Territories.Count));

      _currentEmployee.Territories.Add(aTerritory);
      _localOutput.Append(string.Format("[{0}] No. of territories after adding the removed one back: {1}\n",
        _nameBasicQuerySyntaxQuery, _currentEmployee.Territories.Count));

      Utility.FlushOutputBuffer(_localOutput, _resultsReporter);
    }


... then I get these:



No errors!
Back to Top
rhaney View Drop Down
Newbie
Newbie


Joined: 06-Jul-2010
Location: Orange, CA
Posts: 12
Post Options Post Options   Quote rhaney Quote  Post ReplyReply Direct Link To This Post Posted: 07-Jul-2010 at 4:02pm

My scenario is a little more involved...I'll use the entities in your example...note this is all from a single entity manager.

Get all territories, store them in a list.
 
Get an Employee with Territories using query.Include(e => e.Territories).
 
Remove a territory from employee.Territories.
 
Find the same territory in the "all territories list" and add it to the employee.
 
Save.
 
In my scenario, I get a FK violation.
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 08-Jul-2010 at 2:47pm
Ok, got it. Actually, the only material difference between what my code does and the scenario you described is the save, which I didn't do. Add that and my code fails as yours does.

I'm filing a bug report on this. Looks like we might be trying to insert the linking record (for the add) without having first performed the delete (for the Remove). Alternatively, we might be able to identify that the two actions cancel each other out and do neither a delete nor an insert.

Thank you for calling the problem to our attention.


Edited by GregD - 08-Jul-2010 at 2:48pm
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down