c# - 如何在主键插入关闭的两个对象之间创建关系?
问题描述
我有 4 个表,IndividualTruck、TruckModel、TruckFeature 和 TruckFeatureAssociation。
IndividualTruck 具有 TruckModel 类型的属性 TruckModel。在分配从 WPF 表单检索的其他属性后,我创建关系并将这些新记录添加到如下所示的相关表中。
IndividualTruck truck = new IndividualTruck();
truck.Colour = Colour; #various other attributes
TruckModel model = new TruckModel();
model.Manufacturer = new Manufacturer; #various other attributes
truck.TruckModel = model; #creating the relationship
#this function checks adds the new truck and saves the table
DAO.AddNewTruck(truck, true);
TruckFeature
表类有int FeatureID
,string Description
和TruckFeatureAssociation : ICollection<TruckFeatureAssociation>
TruckFeatureAssociation
表类有int TruckID
、int FeatureID
和。Feature: TruckFeature
Truck: IndividualTruck
我有一个列表框,可以从表格中选择多个功能TruckFeature
,它是一个有四个条目的表格(空调、装载后门、警报系统和无钥匙门)。
我试图遍历所选功能的列表并检索FeatureID
选择分配的那些以分配给featureID
关联表,该关联表是两列TruckID
和FeatureID
两个主键。
当我将数据保存到表中时,出现 SQL 错误
SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“TruckFeature”中插入标识列的显式值。
无法插入显式值,因为插入已关闭
如何在不更改此插入关闭条件的情况下创建此关系?TIA。抱歉,我对 .NET 和 C# 真的很陌生。
更新:
for (int i = featureListBox.SelectedItems.Count - 1; i >= 0; --i)
{
TruckFeatureAssociation association = new TruckFeatureAssociation();
TruckFeature truckFeature = new TruckFeature();
string feature = featureListBox.SelectedItems[i].ToString();
truckFeature = DAO.SearchBySelected(feature);
association.Feature = truckFeature;
association.Truck = truck;
DAO.addNewFeatureAssc(association);
}
和
public static void addNewFeatureAssc(TruckFeatureAssociation ff)
{
using (DAD_BaldipContext ctx = new DAD_BaldipContext())
{
ctx.TruckFeatureAssociation.Add(ff);
ctx.SaveChanges();
}
}
错误显示在 ctx.savechanges() 旁边;
解决方案
使用引用(导航属性)时,您需要使用相同的 DbContext 实例执行所有提取和保存。这里的代码会有问题:
public static TruckFeature SearchBySelected(string feature)
{
using(DAD_BaldipContext ctx = new DAD_BaldipContext())
{ ... }
}
如果每个方法都实例化具有using()
范围的 DbContext,则返回的 TruckFeature 将不会被您用来保存关联的 DbContext 实例“知道”。
使用 MVC,这可以通过使用 DI(依赖注入)来确保单个 DbContext 实例与请求相关联来相当容易地进行管理,因此所有服务等都将在其构造函数中注入该单个实例。
使用 WPF,它通常需要更多的手动管理。这通常意味着使用一个工作单元模式来管理 DbContext 的生命周期范围。但是,首先,您可以通过在操作的“顶级”级别限定 DbContext 并将其传递给各种调用来管理它:
public static TruckFeature SearchBySelected(string feature, DAD_BaldipContext context)
{
TruckFeature ff = context.TruckFeature.Where(f => f.Description == feature).FirstOrDefault();
return ff;
}
实际上,像这样的方法可能并不实用,只需通过 DbContext 在单个using
范围内获取数据。
using (var context = new DAD_BaldipContext())
{
IndividualTruck truck = new IndividualTruck
{
truck.Colour = Colour; #various other attributes
TruckModel = new TruckModel
{
Manufacturer = new Manufacturer { ... }
} // Assuming you need to create a new model, otherwise...
// TruckModel = context.TruckModels.Single(x => /* Query to find the correct model selected. */);
};
for (int i = featureListBox.SelectedItems.Count - 1; i >= 0; --i)
{
string feature = featureListBox.SelectedItems[i].ToString();
TruckFeatureAssociation association = new TruckFeatureAssociation
{
Feature = context.Features.Single(x => x.Description == feature);
}
truck.TruckFeatures.Add(association);
}
context.SaveChanges();
}
这假设 IndividualTruck.TruckFeatures 是卡车和特征之间的多对多关系。如果 TruckFeatures 使用影子链接实体(IndividualTruck 包含一组功能而不是 TruckFeatures),则:
for (int i = featureListBox.SelectedItems.Count - 1; i >= 0; --i)
{
string feature = featureListBox.SelectedItems[i].ToString();
truck.Features.Add(context.Features.Single(x => x.Description == feature));
}
推荐阅读
- laravel - 方法 Illuminate\Translation\Translator::getDefault 不存在
- javascript - 如何使用 Javascript 删除 PDF 中的表单域?
- flutter - 在 Dart 中使用 Ed25519 算法生成 JWS(json Web 签名)
- python - 'style.theme_create' python 的问题
- applescript - 在AppleScript中从列表中选择的枚举关联数组
- python - Cloud Scheduler 调用的 GCP Cloud Run 应用的当前最大超时是多少
- python - 使用 namedtuple 使用 Python 将 txt 转换为 JSON
- regex - Azure 数据资源管理器,Kusto:替换正则表达式问题
- vue.js - vue-recaptcha 增加过期时间
- android - 通过 termux 命令行启动任何应用程序,例如 chrome、youtube 和其他一些应用程序,如 cryptotabbrowser