首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >首先在实体框架代码中添加多对多关系

首先在实体框架代码中添加多对多关系
EN

Stack Overflow用户
提问于 2011-11-22 05:08:56
回答 1查看 554关注 0票数 0

我想在多个现有实体和另一个现有实体之间添加关系。这是我的模型:

代码语言:javascript
复制
public class Term
{
    public int TermId { get; set; }
    public virtual ICollection<SubForm> SubForms { get; set; }
}

public class SubForm
{
    public int SubFormId { get; set; }
    public virtual ICollection<Term> Terms { get; set; }
}

我有一个更新仓库的方法,如下所示:

代码语言:javascript
复制
public IQueryable<Term> GetTerms()
{
    IQueryable<Term> query = db.Terms.AsNoTracking();
    return query;
}

public Term UpdateTerm(Term term, IEnumerable<Expression<Func<Term, object>>> properties)
{
    if (term.TermId == 0)
    {
        throw new InvalidOperationException("Term does not exist");
    }
    db.Terms.Attach(term);
    if (properties != null)
    {
        foreach (var selector in properties)
        {
            string propertyName = Helpers.PropertyToString(selector.Body);
            db.Entry(term).Property(propertyName).IsModified = true;
        }
    }
    db.SaveChanges();
    return term;
}

现在,我假设当我在我的服务层中进行以下调用时,这将会起作用:

代码语言:javascript
复制
public void AddFormToTerm(int termId, int formId)
{
    var term = termsRepository.GetTerms().FirstOrDefault(t => t.TermId == termId);
    var subForms = termsRepository.GetSubForms().Where(t => t.FormId == formId);

    //I assume this would work by adding existing forms to an existing term.
    foreach (var subForm in subForms)
    {
        term.SubForms.Add(subForm);
    }

    termsRepository.UpdateTerm(term, null);
}

不幸的是,这没有更新,当我检查数据库时,中间表中没有任何东西。也没有抛出异常。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-22 07:14:08

在这种情况下使用AsNoTracking就是问题所在。如果没有AsNoTracking,它将会工作。您必须记住,您只能使用更改跟踪机制来更新多对多关系。但是在您的代码中,当您在UpdateTerm方法中调用Attach时,EF上下文将第一次知道termSubForms集合。EF没有注意到您确实向term添加了SubForms,因为这些实体没有附加到上下文(因为您使用了AsNoTracking = "EF,请不要附加到上下文!“)。但是在调用SaveChanges = No change = No数据库命令之前,Attach之后什么也没有发生。因此,删除AsNoTracking (或者创建另一个方法或参数来加载跟踪)是最好的选择。其他一切都会涉及到像这样的丑陋的“把戏”:

代码语言:javascript
复制
public Term UpdateTerm(Term term, ...)
{
    //...

    // Restore the state before adding the subforms = current state in DB
    var tempSubForms = term.SubForms;
    term.SubForms = null;

    // Inform EF about this state = term exists, subforms exist
    // in DB but no relationships
    db.Terms.Attach(term);
    foreach (var subForm in tempSubForms)
        db.SubForms.Attach(subForm);

    // Change the state: EF change tracking recognizes this
    term.SubForms = tempSubForms;

    //...

    // EF now will send INSERT statements for the join table
    db.SaveChanges();
    return term;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8218556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档