C# 实体框架多对多赢得';救不了

C# 实体框架多对多赢得';救不了,c#,asp.net-mvc,entity-framework,many-to-many,C#,Asp.net Mvc,Entity Framework,Many To Many,我有一个简单的多对多模型。产品类别。每一个都有另一个的虚拟列表。我创建的产品如下所示: product = new Product() { AccountId = this.AccountId, Name = this.ProductName, Price = this.ProductPrice, Slug = this.ProductSlug, Sku = this.ProductSku, Favorite = true, Categor

我有一个简单的多对多模型。产品类别。每一个都有另一个的虚拟列表。我创建的产品如下所示:

product = new Product()
{
    AccountId = this.AccountId,
    Name = this.ProductName,
    Price = this.ProductPrice,
    Slug = this.ProductSlug,
    Sku = this.ProductSku,
    Favorite = true,
    Categories = new List<Category>()
                {
                    category 
                }
};

product.Id = productManager.Save(product);
product=新产品()
{
AccountId=this.AccountId,
Name=this.ProductName,
Price=this.ProductPrice,
Slug=this.ProductSlug,
Sku=this.ProductSku,
Favorite=true,
类别=新列表()
{
类别
}
};
product.Id=productManager.Save(产品);
那么,当我去保存它时,它不会保存多对多。我在谷歌上搜索并尝试了这段代码的许多不同版本,但仍然一无所获:

public new String Save(Product data)
{
    try
    {
        var entity = GetById(data.Id);

        if (entity == null)
        {
            this.Context.Set<Product>().Add(data);
        }
        else
        {
            this.Context.Entry(entity).CurrentValues.SetValues(data);
        }

        data.Id = this.Context.SaveChanges();

        var product = Context.Products
            .Include("Categories")
            .FirstOrDefault(t => t.Id == data.Id);

        /**
            * Categories
            */
        var categories = this.Context.Categories
            .Where(t => t.AccountId == data.AccountId);

        var productCategories = new List<Category>();

        if (data.SelectedCategoryIds != null && data.SelectedCategoryIds.Any())
        {
            productCategories.AddRange(categories
                .Where(category => data.SelectedCategoryIds.Contains(category.Id)));
        }

        product.Categories.Clear();
        product.Categories.AddRange(productCategories);

        this.Context.SaveChanges();

        return data.Id;
    }
    catch (Exception ex)
    {
        Log.Error(ex);

        return null;
    }
}
公共新字符串保存(产品数据)
{
尝试
{
var entity=GetById(data.Id);
if(实体==null)
{
this.Context.Set().Add(数据);
}
其他的
{
this.Context.Entry(entity).CurrentValues.SetValues(data);
}
data.Id=this.Context.SaveChanges();
var product=Context.Products
.包括(“类别”)
.FirstOrDefault(t=>t.Id==data.Id);
/**
*类别
*/
var categories=this.Context.categories
其中(t=>t.AccountId==data.AccountId);
var productCategories=新列表();
if(data.SelectedCategoryIds!=null&&data.SelectedCategoryIds.Any())
{
productCategories.AddRange(类别
.Where(category=>data.selectedCategoryId.Contains(category.Id));
}
product.Categories.Clear();
product.Categories.AddRange(productCategories);
this.Context.SaveChanges();
返回data.Id;
}
捕获(例外情况除外)
{
日志错误(ex);
返回null;
}
}

我错过了什么?为什么它不能坚持我的多对多分类?

从技术上讲,这不是一个答案,但评论太长了,需要说明。看起来你试图抽象一些实体框架的东西,但这绝对是错误的做法。例如,在我的一个项目中,我有一个将实体框架从我的应用程序的其余部分抽象出来的服务,下面是一些相关的代码来说明区别:

public virtual void Update<TEntity>(TEntity entity)
    where TEntity : class
{
    context.Set<TEntity>().Attach(entity);
    context.Entry(entity).State = EntityState.Modified;
}

public virtual void Save()
{
    try
    {
        context.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        var errorMessages = ex.EntityValidationErrors
            .SelectMany(x => x.ValidationErrors)
            .Select(x => x.ErrorMessage);
        var fullErrorMessage = string.Join("; ", errorMessages);
        var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
        throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
    }
}
然后,保存更改所需的唯一其他事项(从我的
save
方法):


就这样。如果仅此代码不足以更新您的实体,那么坦率地说,您做错了什么,您需要解开代码并找出原因。

除了无法保存之外,您还有其他详细信息吗?它会引发异常吗?有什么东西击中DB了吗?另外,将产品Id设置为context.SaveChanges()的结果似乎很奇怪。该方法返回写入数据库的对象数,而不是Id。为什么?让我详细说明一下。为什么?不过,说真的,为什么要创建一个
Save
方法来完成这一切呢?您基本上是在实体框架中重新创建
SaveChanges
,但没有做得那么好。@Smith.h.Neil-也不例外。这个产品节省了很多钱。类别是唯一不持久的东西。就像@ChrisPratt所说的,你是否尝试只附加产品,然后调用context.SaveChanges()而不是使用你的save方法?@Chris-我不能只调用SaveChanges。当我从视图bc传回数据时,数据没有附加。我没有保持上下文打开。另外,整个第一部分实际上是在一个通用的save方法中,我在这里没有展示,但是是相同的代码。
var entity = new Something { ... };
service.Update<Something>(entity);
service.Save();
context.Set<Product>().Attach(product);
context.Entry(product).State = EntityState.Modified;
context.SaveChanges();