Search code examples
servicestackormlite-servicestack

Servicestack OrmLite deleting many to many


Let's say I have a ListingEvent class and a UserAccount class.

A ListingEvent can have many UsersAttending and a UserAccount can attend many ListingEvents.

The classes look like:

public class UserAccount
{
    [AutoIncrement]
    [PrimaryKey]
    public int Id {
        get ;
        set;
    }

    public string Name {
        get ;
        set;
    }

    public UserAccount()
    {
        ListingEventsAttending = new List<UserAccountListingEvent> ();
    }

    [Reference]
    public List<UserAccountListingEvent> ListingEventsAttending {
        get;
        set;
    }
}

public class UserAccountListingEvent{
    [AutoIncrement]
    [PrimaryKey]
    public int Id {
        get;
        set;
    }

    public Model.AttendingStatus Status { get; set; }

    [References(typeof(UserAccount))]
    public int UserAccountId {
        get;
        set;
    }

    [References(typeof(ListingEvent))]
    public int ListingEventId {
        get;
        set;
    }
}

public class ListingEvent
{
    public ListingEvent()
    {
        UsersAttending = new List<UserAccountListingEvent>();
    }

    [AutoIncrement]
    [PrimaryKey]
    public int Id {
        get ;
        set;
    }

    public string Name { get; set; }

    [Reference]
    public List<UserAccountListingEvent> UsersAttending { get; set; }

    public void RemoveUserAttending(UserAccount user)
    {
        if (user == null)
        {
            return;
        }

        UsersAttending.RemoveAll(u => u.UserAccountId == user.Id);
    }
}

And I get a ListingEvent that has my UserAccount attending with:

var listingEvent = db.LoadSingleById<Model.ListingEvent> (request.Id);

And I can see that the user with the correct Id is attending so call RemoveUserAttending to remove the user. I can now see the user is not attending so I call:

db.Save (listingEvent, references: true);

But - now when I go to fetch that ListingEvent again the user is back to attending.

So my question is:

  1. should the above work as expected?
  2. if not - how should I be doing this?

Solution

  • db.Save() only INSERT or UPDATE entities i.e. it doesn't DELETE them.

    To delete, retrieve the entities or entity Ids you want to delete and use OrmLite's db.Delete* API's explicitly, e.g. something like:

    var removeUsersAttendingIds = listingEvent.UsersAttending
        .Where(u => u.UserAccountId == user.Id)
        .Select(u => u.Id);
    
    db.DeleteByIds<UserAccountListingEvent>(removeUsersAttendingIds);