0

エンティティのレコードを削除する必要がありますが、それに関連する別のエンティティのすべてのレコードを保持します。

削除するエンティティレコードは次のとおりです。

public class Ask
{
    // Primary properties
    public int Id { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }
    public DateTime DateCreated { get; set; }
}

Askレコードを削除した後に保持したい関連レコードは、MessageAskタイプです。

public class Message
{
    // Primary properties
    public int Id { get; set; }
    public string NameFrom { get; set; }
    public string EmailFrom { get; set; }
    public string TelephoneFrom { get; set; }
    public string Title { get; set; }
    public string MessageText { get; set; }
    public bool? Approved { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateRead { get; set; }

    // Navigation properties
    public Member MemberFrom { get; set; }
    public Member MemberTo { get; set; }
    public MessageType MessageType { get; set; }
    public Message MessageParent { get; set; }
}

public class MessageAsk : Message
{
    public Ask Ask { get; set; }
}

再開して、Askを削除し、関連するすべてのMessageAskを保持したいと思います。

編集:私はサービスを使用します削除:

    private readonly IRepository<Ask> _askRepository;
    private readonly IRepository<MessageAsk> _messageAskRepository;

    public bool Delete(int askId)
    {
        try
        {
            Ask askToDelete = _askRepository.GetById(askId);

            IList<MessageAsk> relatedMessageAsks = _messageAskRepository.Query.Where(m => m.Ask.Id == askId).ToList();

            _askRepository.Delete(askToDelete);

            _askRepository.Save();

         }
        catch 
        { 
            return false; 
        }

        return true;
    }

そして、リポジトリを使用してエンティティを削除します。

public class Repository<T> : IRepository<T> where T : class
{
    protected DbContext _dataContext;
    protected DbSet<T> _dbSet;

    public Repository(DbContext context)
    {
        _dataContext = context;
        _dbSet = _dataContext.Set<T>();
    }

    public T NewEntityInstance()
    {
        return _dbSet.Create();
    }

    public void Delete(T entity)
    {
        if (_dataContext.Entry(entity).State == EntityState.Detached)
        {
            _dbSet.Attach(entity);
        }
        _dbSet.Remove(entity);
    }

   public virtual void Delete(object id)
    {
        T entity = _dbSet.Find(id);

        Delete(entity);
    }

    public T GetById(int id)
    {
        return _dbSet.Find(id);
    }

    public virtual IQueryable<T> Query
    {
        get
        {
            return _dbSet.AsNoTracking(); <------ SOURCE OF THE PROBLEM - I HAD TO REMOVE THE ASNOTRACKING OPTION TO SOLVE THE PROBLEM
        }
    }

}

私が今得るエラー:

"The DELETE statement conflicted with the REFERENCE constraint "FK_Messages_Asks". The conflict occurred in database "Heelp", table "dbo.Messages", column 'Ask_Id'.

ありがとう

4

1 に答える 1

1

関係がオプションである場合(つまり、テーブルからMessageAskテーブルへの外部キーが値をAsk許可するNULL場合)、次のように行うことができます。

using (var context = new MyContext())
{
    var askToDelete = context.Asks.Single(a => a.Id == askToDeleteId);
    var relatedMessageAsks = context.MessageAsks
        .Where(m => m.Ask.Id == askToDeleteId)
        .ToList();
    // or just: context.MessageAsks.Where(m => m.Ask.Id == askToDeleteId).Load();

    context.Asks.Remove(askToDelete);
    // or DeleteObject if you use ObjectContext

    context.SaveChanges();
}

(または、コンテキストに派生型のセットがない場合context.Messages.OfType<MessageAsk>()...の代わりに)context.MessageAsks...

MessageAsk.Askここでプロパティをnull明示的に設定する必要はありません。EFは、が削除されると自動的にそれを行い、データベース内のFK=でaskToDelete更新します。MessageAskNULL

プリンシパル( )が削除されるNULLときにデータベース内の参照外部キー制約に違反するため、関係が必要な場合(FKのsは許可されません)は機能しません。askToDeleteその場合、を削除する前に、relatedMessageAsksを別のに割り当てる必要があります。AskaskToDelete

于 2013-03-11T19:23:15.507 に答える