现在我明白了。
当使用客户机进行测试时,mvc会接收带有json数据的请求,并正确创建模型。
然而,mvc不知道你想要的是同样的
Image
对于产品和品牌,它将为每个产品和品牌创建一个实例,如下所示(我简化了示例):
var product = new Product();
var brand = new Brand();
product.Image = new Image();
product.Brand = brand;
brand.Image = new Image(); // new image with same info...
同样,实体框架将假设它们是具有相同数据的两个不同图像。只要让它知道它是一样的,通过在你的操作中执行类似的操作(当然,你会创建更好的代码,这只是一个简单的示例):
[HttpPost]
public IActionResult Create([FromBody] Product product)
{
if (product == null)
return BadRequest();
// If the image already exists...nullify image so EF won't try to insert a new one...
if (product.ImageId > 0)
product.Image = null;
// If the image already exists...and the brand doesn't have an existing image, use the same image and nullify the brand's image as well...
if (product.ImageId > 0 && product.Brand != null && !(product.Brand.ImageId > 0))
{
product.Brand.ImageId = product.ImageId;
product.Brand = null;
}
// If product is reveiving a new image...and the brand doesn't have an existing image, use the same new image...
if (product.Image != null && product.Brand != null && !(product.Brand.ImageId > 0))
product.Brand.Image = product.Image;
var result = _productsService.Add(product, m => m.Name == product.Name);
if (result)
{
return CreatedAtRoute("GetProducts", new { id = product.Id }, product);
}
return BadRequest("Item not added");
}
为了在控制台应用程序中进行测试,我复制了它,如下所示。某些类别:
public class Brand
{
public int Id { get; set; }
public virtual Image Image { get; set; }
public int ImageId { get; set; }
}
public class Image
{
public int Id { get; set; }
}
public class Product
{
public int Id { get; set; }
public virtual Image Image { get; set; }
public virtual Brand Brand { get; set; }
public int ImageId { get; set; }
public int BrandId { get; set; }
}
这个
DbContext
配置:
public class MyDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Brand> Brands { get; set; }
public DbSet<Image> Images { get; set; }
public MyDbContext()
: base("name=MyDbContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Properties<int>().Where(p => p.Name == "Id").Configure(p => p.IsKey());
modelBuilder.Entity<Product>().HasRequired(p => p.Brand).WithMany().HasForeignKey(p => p.BrandId);
modelBuilder.Entity<Product>().HasRequired(p => p.Image).WithMany().HasForeignKey(p => p.ImageId);
modelBuilder.Entity<Brand>().HasRequired(p => p.Image).WithMany().HasForeignKey(p => p.ImageId);
}
}
最后是代码本身。
在第一种情况下,我使用相同的实例:
class Program
{
static void Main(string[] args)
{
using (var db = new MyDbContext())
{
var image = new Image();
var product = new Product();
var brand = new Brand();
product.Image = image;
product.Brand = brand;
brand.Image = image; // same instance
db.Products.Add(product);
db.SaveChanges();
}
}
}
我的结果是:
然后我再次运行,现在使用一个新实例:
class Program
{
static void Main(string[] args)
{
using (var db = new MyDbContext())
{
var image = new Image();
var product = new Product();
var brand = new Brand();
product.Image = image;
product.Brand = brand;
brand.Image = new Image();
db.Products.Add(product);
db.SaveChanges();
}
}
}
现在我们有两个新图像: