I am using Entity Framework 4.1 - Code First and I have a many to many relationship between my User
and Message
entities. The relationship is mapped through another entity UserMessage
. The messaging system I've implemented resembled that of Gmail, which means messages are "threads" where replies of a message are shown along the initial message.
Now I'm trying to delete a message from a user's inbox, but I do not want it to end up being deleted from the database because the other user might not choose to delete the message from his/her inb开发者_JAVA技巧ox. Unfortunately, my code is throwing the following exception:
A relationship from the 'UserMessage_Receiver' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'UserMessage_Receiver_Source' must also in the 'Deleted' state.
Here's the code involved:
public class UserMessage
{
public int Id { get; set; }
public DateTime? LastViewed { get; set; }
public bool IsRead { get; set; }
public virtual Message Message { get; set; }
public virtual User Sender { get; set; }
public virtual User Receiver { get; set; }
}
public void DeleteFromInbox(int messageId, User user)
{
var message = _repository.First<UserMessage>(c=>c.Message.Id.Equals(messageId));
var replies = GetReplies(user, messageId);
foreach (var reply in replies)
{
if (user.ReceivedMessages.Contains(reply))
{
user.ReceivedMessages.Remove(reply);
reply.Receiver = null;
}
if (user.SentMessages.Contains(reply))
{
user.SentMessages.Remove(reply);
reply.Sender = null;
}
}
message.Receiver = null;
user.ReceivedMessages.Remove(message);
}
So where did I go wrong?
Removing entity from navigation property will not mark it as deleted. It will only remove relation - that mean that FK in UserMessage
will be set to null and if it is not nullable you will get your exception. You must do something like:
foreach (var reply in replies)
{
if (user.ReceivedMessages.Contains(reply))
{
user.ReceivedMessages.Remove(reply);
reply.Receiver = null;
}
if (user.SentMessages.Contains(reply))
{
user.SentMessages.Remove(reply);
reply.Sender = null;
}
_repository.Delete(reply);
}
Edit:
The mentioned code deletes UserMessage
- not Message
. As I think about your model your new problem is obvious. Your first exception was caused by multiplicity constraints on the UserMessage
entity - Receiver
is mandatory so you cannot remove relation to receiver without removing whole UserMessage
but once you remove UserMessage
(and there is no other receiver of the message) it will remove it from sender as well.
Your model is wrong. Even if you make Receiver
optional it will result in UserMessage
instances without receiver and unless you store receiver list somewhere else you will lost information about one of original receivers (when sender open the message again from his outbox he will most probably not see the receiver).
精彩评论