如何创建Linq到Sql类型的临时记录而不引起重复的密钥问题?
我有基于DataGridView生成记录的代码。这些记录是临时的,因为其中一些记录已经存在于数据库中如何创建Linq到Sql类型的临时记录而不引起重复的密钥问题?,linq,linq-to-sql,Linq,Linq To Sql,我有基于DataGridView生成记录的代码。这些记录是临时的,因为其中一些记录已经存在于数据库中 Crop_Variety v = new Crop_Variety(); v.Type_ID = currentCropType.Type_ID; v.Variety_ID = r.Cells[0].Value.ToString(); v.Description = r.Cells[1].Value.ToString();
Crop_Variety v = new Crop_Variety();
v.Type_ID = currentCropType.Type_ID;
v.Variety_ID = r.Cells[0].Value.ToString();
v.Description = r.Cells[1].Value.ToString();
v.Crop = currentCrop;
v.Crop_ID = currentCrop.Crop_ID;
不幸的是,在这段代码中,因为我说v.Crop=currentCrop,
现在currentCrop.Crop_变种包括这个临时记录。当我插入这个网格的新记录时,它们引用了相同的作物记录,因此数据库中已经存在的这些临时记录在我提交时显示了两次,导致重复的键错误
我有一套完整的系统,可以根据用户所做的事情来检测哪些记录需要添加,哪些记录需要删除,但这种对参考文献的无情跟踪却让它变得一团糟
有没有办法阻止Linq To Sql自动将这些临时记录添加到其表集合中?当您指定实体对象引用时,您正在创建两个对象之间的链接。在这里,您可以这样做:
v.Crop = currentCrop;
只有一种方法可以避免这种情况:修改生成的代码或生成/编写自己的代码。我决不会这样做
我认为编写自定义DTO类而不是重用生成的实体会更好。这两种方法我都做过,我更喜欢后一种
编辑:以下是一些生成的示例代码:
[global::System.Data.Linq.Mapping.AssociationAttribute(Name="RssFeed_RssFeedItem", Storage="_RssFeed", ThisKey="RssFeedID", OtherKey="ID", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
public RssFeed RssFeed
{
get
{
return this._RssFeed.Entity;
}
set
{
RssFeed previousValue = this._RssFeed.Entity;
if (((previousValue != value)
|| (this._RssFeed.HasLoadedOrAssignedValue == false)))
{
this.SendPropertyChanging();
if ((previousValue != null))
{
this._RssFeed.Entity = null;
previousValue.RssFeedItems.Remove(this);
}
this._RssFeed.Entity = value;
if ((value != null))
{
value.RssFeedItems.Add(this);
this._RssFeedID = value.ID;
}
else
{
this._RssFeedID = default(int);
}
this.SendPropertyChanged("RssFeed");
}
}
}
正如您所看到的,生成的代码通过说“value.rssfeedeitems.Add(this);”来建立链接
如果有多个实体,则需要多个DTO,您可以使用反射编码生成DTO类。指定实体对象引用时,您正在创建两个对象之间的链接。在这里,您可以这样做:
v.Crop = currentCrop;
只有一种方法可以避免这种情况:修改生成的代码或生成/编写自己的代码。我决不会这样做
我认为编写自定义DTO类而不是重用生成的实体会更好。这两种方法我都做过,我更喜欢后一种
编辑:以下是一些生成的示例代码:
[global::System.Data.Linq.Mapping.AssociationAttribute(Name="RssFeed_RssFeedItem", Storage="_RssFeed", ThisKey="RssFeedID", OtherKey="ID", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
public RssFeed RssFeed
{
get
{
return this._RssFeed.Entity;
}
set
{
RssFeed previousValue = this._RssFeed.Entity;
if (((previousValue != value)
|| (this._RssFeed.HasLoadedOrAssignedValue == false)))
{
this.SendPropertyChanging();
if ((previousValue != null))
{
this._RssFeed.Entity = null;
previousValue.RssFeedItems.Remove(this);
}
this._RssFeed.Entity = value;
if ((value != null))
{
value.RssFeedItems.Add(this);
this._RssFeedID = value.ID;
}
else
{
this._RssFeedID = default(int);
}
this.SendPropertyChanged("RssFeed");
}
}
}
正如您所看到的,生成的代码通过说“value.rssfeedeitems.Add(this);”来建立链接
如果您有许多实体,您将需要许多DTO,您可以使用反射代码生成DTO类。我建议重新访问用记录填充DataGridView(grid)的代码 然后重新访问对GridView中的项进行操作的代码,记住可以使用以下代码从网格行获取绑定项:
public object GridSelectedItem
{
get
{
try
{
if (_grid == null || _grid.SelectedCells.Count < 1) return null;
DataGridViewCell cell = _grid.SelectedCells[0];
DataGridViewRow row = _grid.Rows[cell.RowIndex];
if (row.DataBoundItem == null) return null;
return row.DataBoundItem;
}
catch { }
return null;
}
}
public object GridSelectedItem
{
得到
{
尝试
{
if(_grid==null | | | u grid.SelectedCells.Count<1)返回null;
DataGridViewCell单元格=_grid.SelectedCells[0];
DataGridViewRow=_grid.Rows[cell.RowIndex];
if(row.DataBoundItem==null)返回null;
返回row.DataBoundItem;
}
捕获{}
返回null;
}
}
您发布的作物品种代码的性质也很难理解。由于作物的多样性似乎是作物的一个子类。当作物尚未绑定到数据库时,这会导致问题,并且在将作物品种添加到上下文时可能会导致问题
对于这种类型的表单应用程序,我通常在表单类中有List\u dataList,然后通过ObjectBindingList或其他方式将主网格绑定到该列表。这样_dataList就可以在需要时保存所有需要持久化的数据(用户单击保存) 我建议重新访问用记录填充DataGridView(grid)的代码 然后重新访问对GridView中的项进行操作的代码,记住可以使用以下代码从网格行获取绑定项:
public object GridSelectedItem
{
get
{
try
{
if (_grid == null || _grid.SelectedCells.Count < 1) return null;
DataGridViewCell cell = _grid.SelectedCells[0];
DataGridViewRow row = _grid.Rows[cell.RowIndex];
if (row.DataBoundItem == null) return null;
return row.DataBoundItem;
}
catch { }
return null;
}
}
public object GridSelectedItem
{
得到
{
尝试
{
if(_grid==null | | | u grid.SelectedCells.Count<1)返回null;
DataGridViewCell单元格=_grid.SelectedCells[0];
DataGridViewRow=_grid.Rows[cell.RowIndex];
if(row.DataBoundItem==null)返回null;
返回row.DataBoundItem;
}
捕获{}
返回null;
}
}
您发布的作物品种代码的性质也很难理解。由于作物的多样性似乎是作物的一个子类。当作物尚未绑定到数据库时,这会导致问题,并且在将作物品种添加到上下文时可能会导致问题
对于这种类型的表单应用程序,我通常在表单类中有List\u dataList,然后通过ObjectBindingList或其他方式将主网格绑定到该列表。这样_dataList就可以在需要时保存所有需要持久化的数据(用户单击保存) 您能再解释一下为什么创建新的
Crop\u Variety
实例,但不希望它们被持久化。还是希望L2S在持久化它们之前找出哪些是重复的?我正在尝试为DataGridView中找到的所有记录创建实例。并非所有数据都有到datagridview的直接映射,因此我不确定是否可以进行任何类型的自动更新/插入。我正在重新调整我的保存代码,因为这个问题在我当前的系统中不断出现,但是如果有更好的方法在处理网格行数据时识别现有记录和新记录,那就太好了。你能解释一下为什么创建新的Crop\u Variety
实例,但不希望它们被持久化吗。还是希望L2S在持久化它们之前找出哪些是重复的?我正在尝试为DataGridView中找到的所有记录创建实例。并非所有数据都有到datagridview的直接映射,因此我不确定是否可以进行任何类型的自动更新/插入。我正在重新调整我的保存代码,因为