C# 如何使用GraphDiff更新表达式树

C# 如何使用GraphDiff更新表达式树,c#,entity-framework,graphdiff,C#,Entity Framework,Graphdiff,我使用的对象图基本上是: public class Resource { public string Forename { get; set; } public string Surname { get; set; } public int EmployeeNumber { get; set; } public ICollection<Skill> Skills { get; set; } } publi

我使用的对象图基本上是:

public class Resource
    {
        public string Forename { get; set; }
        public string Surname { get; set; }
        public int EmployeeNumber { get; set; }
        public ICollection<Skill> Skills { get; set; }
    }
public class Skill
    {
        public int SkillId{get; private set;}
        public Technology Technology { get; set; }
        public SkillCategory Category { get; set; }
        public SkillCompetency Competency { get; set; }    

    }
公共类资源
{
公共字符串名{get;set;}
公共字符串姓氏{get;set;}
public int EmployeeNumber{get;set;}
公共i收集技能{get;set;}
}
公开课技能
{
public int SkillId{get;private set;}
公共技术{get;set;}
公共技能类别{get;set;}
公共技能能力{get;set;}
}
通过选择现有技术、技能类别、技能能力的组合,可以向用户添加新技能。我一直在尝试(但失败!)使用GraphDiff来防止EF尝试添加重复的技术、技能类别和技能能力记录。 使用GraphDiff似乎应该很容易实现,但作为EF的新手,我只需要找到GraphDiff就够了


有什么想法吗?

GraphDiff基本上区分了两种关系:拥有和关联。“拥有”可以解释为“属于”的一部分,这意味着拥有的任何东西都将与其所有者一起插入/更新/删除。GraphDiff处理的另一种关系是关联的,这意味着在更新图形时,GraphDiff只更改与实体的关系,而不更改关联实体本身

回到您的场景:您不想要重复的
技术
类别
能力
实体,但是
技能
只是这些实体的组合,所以重复的
技能
是可以的。为了使用GoDIFF建模,您可以把代码< >代码>作为代码<资源> <代码>(由代码<资源/代码>拥有)和<代码>技术>代码>代码> >类别< /代码>和<代码>权限> <代码>作为代码>技能> /代码>的关联。这是这样映射的:

// these three entities are all managed separately and have already been saved elsewhere
Technology entityFrameworkCodeFirst;
Category objectRelationalMappers;
Competency notThatIncompetent;

using (DbContext context = new WhatEverYourContextIsNamed())
{
    Resource developer = new Resource
    {
        Skills = new List<Skill> 
        {  
            new Skill
            {
                Technology = entityFrameworkCodeFirst,
                Category = objectRelationalMappers,
                Competency = notThatIncompetent,
            }
        } 
    };
    context.UpdateGraph(developer, 
        map => map.OwnedCollection(r => r.Skills, 
            with => with.AssociatedEntity(skill => skill.Technology)
                        .AssociatedEntity(skill => skill.Category)
                        .AssociatedEntity(skill => skill.Competency)));
    context.SaveChanges();
}
//这三个实体都是单独管理的,并且已经保存在其他地方
技术实体框架代码优先;
类别对象关系映射器;
能力,而不是无能;
使用(DbContext context=newwhateveryourcontextisnamed())
{
资源开发者=新资源
{
技能=新列表
{  
新技能
{
技术=EntityFrameworkCode优先,
类别=对象关系映射器,
能力=并非无能,
}
} 
};
context.UpdateGraph(开发者、,
map=>map.OwnedCollection(r=>r.Skills,
with=>with.AssociatedEntity(skill=>skill.Technology)
.AssociatedEntity(skill=>skill.Category)
.关联实体(技能=>技能.能力));
SaveChanges();
}

此外,如果GraphDiff的行为异常,请不要使用NuGet软件包,而是从源代码生成,因为该软件包目前已经过时。不过,我希望它很快就会更新。谢谢安迪,我只是在尝试你的答案。GraphDiff似乎完全可以实现我们想要的功能,因此如果我们能够实际使用它,那就太好了:-)GraphDiff的NuGet包昨天已经更新。好的,我已经尝试了你的建议。我想你可能误解了我的问题。我面临的问题是,当我向资源中添加新技能时,技术、技能类别、技能能力的关联对象将作为新项目添加。因为这些都是参考数据,所以我不想添加它们。我想我要做的是将技术、技能类别、技能能力作为关联的技能集合,这反过来又是关联的资源集合,但我似乎无法配置它。你是对的,我昨天误解了你的问题-我更新了我的答案,希望我没有再次误解你:)谢谢你,安迪。上面的代码就是我在你最初的回复后真正了解自己的地方。然而,它没有工作-我得到了一个复制的开发人员!我的场景是:1)创建一个开发人员,添加一个技能,然后更新/保存实体2)使用同一个开发人员添加第二个技能,然后更新并保存这给了我第二个开发人员记录。我的问题是在第一次更新/保存后,开发人员id没有用db标识值更新。我执行的代码是:context.UpdateGraph(developer,…)我假设,因为开发人员是引用类型,所以它的id将刚刚更新。一旦我将代码更改为:developer=context.UpdateGraph(developer,…),一切都很顺利。而且我认为重建也有帮助。非常感谢你的帮助。