C# 如何在EF core中实现添加相关数据的方法?
如何实现在EF core中添加相关数据的方法?哪些对象需要提交给add方法,它应该返回什么?我需要相关数据加载项数据库,例如:C# 如何在EF core中实现添加相关数据的方法?,c#,entity-framework-core,linq-to-entities,C#,Entity Framework Core,Linq To Entities,如何实现在EF core中添加相关数据的方法?哪些对象需要提交给add方法,它应该返回什么?我需要相关数据加载项数据库,例如: { "productId": 0, "number": "xxx", "amount": 5.65, "primeCost": 20.33, "productTypeId": 0, "parameters": [ {
{
"productId": 0,
"number": "xxx",
"amount": 5.65,
"primeCost": 20.33,
"productTypeId": 0,
"parameters": [
{
"id": 0,
"name": "Type",
"value": null
},
{
"id": 3,
"name": "steel grade",
"value": "CK45"
},
{
"id": 4,
"name": "diameter",
"value": "40"
}
]
}
以下是我的模型类:
public class Product //: BaseObject
{
public int Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCost { get; set; }
[ForeignKey("ProductTypeId")]
public int ProductTypeId { get; set; }
public virtual ProductType ProductType { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductType //: BaseObject
{
public int Id { get; set; }
public string NameType { get; set; }
public ICollection<Parameter> Parameters { get; set; } = new List<Parameter>();
public ICollection<Product> Products { get; set; } = new List<Product>();
}
public class Parameter //: BaseObject
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("ProductTypeId")]
public int ProductTypeId { get; set; }
public ProductType ProductType { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductParameter //: BaseObject
{
public int Id { get; set; }
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public int ParameterId { get; set; }
public virtual Parameter Parameter { get; set; }
public string Value { get; set; }
}
公共类产品//:BaseObject
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串编号{get;set;}
公共双倍金额{get;set;}
公共双素数成本{get;set;}
[外键(“ProductTypeId”)]
public int ProductTypeId{get;set;}
公共虚拟ProductType ProductType{get;set;}
public ICollection ProductParameters{get;set;}=new List();
}
公共类ProductType/:BaseObject
{
公共int Id{get;set;}
公共字符串名称类型{get;set;}
公共ICollection参数{get;set;}=new List();
公共ICollection产品{get;set;}=new List();
}
公共类参数//:BaseObject
{
公共int Id{get;set;}
公共字符串名称{get;set;}
[外键(“ProductTypeId”)]
public int ProductTypeId{get;set;}
公共ProductType ProductType{get;set;}
public ICollection ProductParameters{get;set;}=new List();
}
公共类ProductParameter/:BaseObject
{
公共int Id{get;set;}
public int ProductId{get;set;}
公共虚拟产品产品{get;set;}
公共int参数id{get;set;}
公共虚拟参数{get;set;}
公共字符串值{get;set;}
}
以下是我的DTO课程:
public class ProductDTO
{
public int ProductId { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
public int ProductTypeId { get; set; }
public string NameType { get; set; }
public ICollection<ParameterDTO> Parameters { get; set; } = new List<ParameterDTO>();
}
public class ParameterDTO
{
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
公共类产品到
{
public int ProductId{get;set;}
公共字符串编号{get;set;}
公共双倍金额{get;set;}
公共双素数costur{get;set;}
public int ProductTypeId{get;set;}
公共字符串名称类型{get;set;}
公共ICollection参数{get;set;}=new List();
}
公共类参数to
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串值{get;set;}
}
我在数据库中添加相关数据的方法的实现:
public async Task<IEnumerable<ProductDTO>> AddProducts(ProductDTO ProductDTO,
List<ParameterDTO> ParameterDTO)
{
var EntryProduct = await _context.Products.FindAsync(ProductDTO.ProductId);
if (EntryProduct == null)
{
_context.Products.Add(new Product
{
Id = ProductDTO.ProductId,
Number = ProductDTO.Number,
Amount = ProductDTO.Amount,
PrimeCostEUR = ProductDTO.PrimeCostEUR,
});
_context.SaveChanges();
foreach (var i in ParameterDTO)
{
var EntryParameter = await _context.Parameters.FindAsync(i.Id);
if (EntryParameter != null)
{
_context.ProductParameters.Add(
new ProductParameter
{
ProductId = ProductDTO.ProductId,
ParameterId = i.Id,
Value = i.Value
});
_context.SaveChanges();
}
}
}
return ProductDTO;
}
public async Task AddProducts(ProductDTO-ProductDTO,
列表参数(到)
{
var EntryProduct=wait_context.Products.FindAsync(ProductDTO.ProductId);
if(EntryProduct==null)
{
_context.Products.Add(新产品)
{
Id=ProductDTO.ProductId,
编号=产品编号,
金额=产品总金额,
PrimeCostur=ProductDTO.PrimeCostur,
});
_SaveChanges();
foreach(参数dto中的变量i)
{
var EntryParameter=wait_context.Parameters.FindAsync(i.Id);
if(EntryParameter!=null)
{
_context.ProductParameters.Add(
新产品参数
{
ProductId=ProductDTO.ProductId,
参数Id=i.Id,
值=i.值
});
_SaveChanges();
}
}
}
将产品返回给客户;
}
我收到以下异常,这是一个编译器错误:
严重性代码说明项目文件行抑制状态
错误CS0266无法将类型“GdmStore.DTO.ProductDTO”隐式转换为“System.Collections.Generic.IEnumerable”。存在显式转换(是否缺少强制转换?)
方法希望返回IEnumerable,但只返回传入的单个产品DTO 签名应为:
public async Task<ProductDTO> AddProducts(ProductDTO ProductDTO, List<ParameterDTO> ParameterDTO)
应该是
[ForeignKey("ProductType")] // FK to the reference property.
public int ProductTypeId { get; set; }
public virtual ProductType ProductType { get; set; }
所有导航属性(如集合和producttype)都应声明为虚拟,否则会出现不一致的行为。如果需要,声明为虚拟的将有权访问延迟加载,其他将保留为#null
Product和Parameter都不应该引用ProductType,从我所看到的,它可能应该只在Product上,以避免非规范化问题。(设置了不同ProductType参数的产品。)
在处理导航属性时,我建议从实体中删除FK属性并使用映射(EF6)/阴影属性。(EF核心)
例如:
public class ProductParameter
{
public int Id { get; set; }
public virtual Product Product { get; set; } // No ProductId/ParameterId
public virtual Parameter Parameter { get; set; }
public string Value { get; set; }
}
modelBuilder.Entity<Product>()
.HasMany(x => x.ProductParameters)
.WithOne(x => x.Product)
.HasForeignKey("ProductId"); // Sets up a shadow property.
我不建议对DbContext(_context)使用模块级变量,因为上下文应该是短期的,以帮助避免一个工作流打算保存而其他代码可能不保存的潜在问题。如果它是由IoC容器注入的,并且作用域为与请求匹配的生存期,那么这不会导致任何问题。只是要小心上下文被打开的时间比需要的时间长
public class ProductParameter
{
public int Id { get; set; }
public virtual Product Product { get; set; } // No ProductId/ParameterId
public virtual Parameter Parameter { get; set; }
public string Value { get; set; }
}
modelBuilder.Entity<Product>()
.HasMany(x => x.ProductParameters)
.WithOne(x => x.Product)
.HasForeignKey("ProductId"); // Sets up a shadow property.
var EntryProduct = _context.Products.Find(ProductDTO.ProductId);
if (EntryProduct != null)
return ProductDTO;
var product = new Product
{
Id = ProductDTO.ProductId,
Number = ProductDTO.Number,
Amount = ProductDTO.Amount,
PrimeCostEUR = ProductDTO.PrimeCostEUR,
};
var parameterIds = ParameterDTO.Select(x => x.Id).ToList();
var parametersToAdd = context.Parameters
.Where(x => parameterIds.Contains(x.ParameterId))
.Select(x => new ProductParameter
{
Product = product,
Parameter = x
}).ToList();
product.ProductParameters.AddRange(parametersToAdd);
await _context.SaveChangesAsync();
return ProductDTO;