C# 如何控制EF插入数据库?

C# 如何控制EF插入数据库?,c#,database,entity-framework,C#,Database,Entity Framework,我有三个表商品,生产者,类别生产者和类别与商品有一对多的关系,我有一个通用的插入方法,代码如下所示 问题是,当我试图插入商品列表时,第一个商品被正确添加,但如果下一个商品具有相同id的类别,它会抛出一个关于主键的异常 但我想控制插入,比如,每次插入表之前检查类别和生产者,如果行已经存在,只需更新它或跳过 使用模型和“我的通用插入”在此处编码: public class Good { [Key] [DatabaseGenerated(DatabaseGeneratedOption.

我有三个表
商品
生产者
类别
<代码>生产者和
类别
商品
有一对多的关系,我有一个通用的插入方法,代码如下所示

问题是,当我试图插入商品列表时,第一个商品被正确添加,但如果下一个商品具有相同id的类别,它会抛出一个关于主键的异常

但我想控制插入,比如,每次插入表之前检查
类别
生产者
,如果行已经存在,只需更新它或跳过

使用模型和“我的通用插入”在此处编码:

public class Good
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }

    public virtual Category Category { get; set; }
    public virtual Producer Producer { get; set; }

    public override string ToString()
    {
        return Id + "/" + Name + "/" + Price + "/" + Category.Name + "/" + Producer.Name + "/" + Producer.Country;
    }
}

public class Producer
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }

    public virtual ICollection<Good> Goods { get; set; }

    public override string ToString()
    {
        return Id + "/" + Name + "/" + Country;
    }
}

public class Category
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Good> Goods { get; set; }

    public override string ToString()
    {
        return Id + "/" + Name;
    }
}

public void AddList(List<T> collection, DbContext GoodsContext)
{
        foreach (var item in collection)
        {
            GoodsContext.Set<T>().Add(item);
            GoodsContext.SaveChanges();
        }
}
公共物品
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共十进制价格{get;set;}
公共虚拟类别{get;set;}
公共虚拟生产者{get;set;}
公共重写字符串ToString()
{
返回Id+“/”+Name+“/”+Price+“/”+Category.Name+“/”+Producer.Name+“/”+Producer.Country;
}
}
公共级制作人
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串国家{get;set;}
公共虚拟ICollection商品{get;set;}
公共重写字符串ToString()
{
返回Id+“/”+姓名+“/”+国家/地区;
}
}
公共类类别
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection商品{get;set;}
公共重写字符串ToString()
{
返回Id+“/”+名称;
}
}
public void AddList(列表集合,DbContext GoodsContext)
{
foreach(集合中的var项)
{
GoodsContext.Set().Add(项);
GoodsContext.SaveChanges();
}
}

您可以首先使用最新发布的for Entity Framework代码轻松实现这一点。我已经发表在了,和。借助于
InsertOrUpdateGraph
方法,它将自动将您的实体设置为
Added
Modified

 foreach (var item in collection)
 {
        // This will set the state of the main entity and all of it's navigational 
        // properties as `Added` or `Modified`.
        GoodsContext.InsertOrUpdateGraph(item);
        GoodsContext.SaveChanges();

        GoodsContext.Entry(item).State = EntityState.Detached;
 }

您可以通过一步一步的演示来阅读,并且可以下载一个示例项目。

您可以首先通过最新发布的实体框架代码轻松实现这一点。我已经发表在了,和。借助于
InsertOrUpdateGraph
方法,它将自动将您的实体设置为
Added
Modified

 foreach (var item in collection)
 {
        // This will set the state of the main entity and all of it's navigational 
        // properties as `Added` or `Modified`.
        GoodsContext.InsertOrUpdateGraph(item);
        GoodsContext.SaveChanges();

        GoodsContext.Entry(item).State = EntityState.Detached;
 }

您可以通过一步一步的演示来阅读,一个示例项目已准备好下载。

您能解释一下我的解决方案的InsertOrUpdateGraph应该是什么样子的吗?我创建了映射并添加了图形操作,但仍然无法理解insertorupdate应该是什么样子。谢谢。@Demsas您必须使用EntityGraphOperations添加
您可以从codeproejct下载并检查示例项目。好的,它按照您所说的方式添加第一个项目,在第二个项目上有一个例外:序列不包含相应的元素;你能解释一下为什么当我试图添加另一个已经存在的商品时,它抛出的异常是:序列不包含相应的元素???@Demsaas你能给我看看你的代码吗?因为,它不应该抛出例外。它在哪一部分抛出?您能解释一下我的解决方案的InsertOrUpdateGraph应该是什么样子的吗?我创建了映射并添加了图形操作,但仍然不能确定insertorupdate应该是什么样子。谢谢。@Demsaas您必须使用EntityGraphOperations添加
您可以从codeproejct下载并检查示例项目。好的,它按照您所说的方式添加第一个项目,在第二个项目上有一个例外:序列不包含相应的元素;你能解释一下为什么当我试图添加另一个已经存在的商品时,它抛出的异常是:序列不包含相应的元素???@Demsaas你能给我看看你的代码吗?因为,它不应该抛出例外。它在哪一部分抛掷?