使用外键更新一行时遇到问题。原理思想是使用泛型方法更新数据库中的行,但是当我在数据库中保存修改时我有一个例外,因此我尝试修改实体的状态,但不修改工作者。
public partial class imcharacteristicsitem
{
public imcharacteristicsitem()
{
this.imvaluesofitemscaracteristics = new HashSet<imvaluesofitemscaracteristic>();
}
public int idCharacteristicItem { get; set; }
public string characteristicItem { get; set; }
public string unitCaracteristicItem { get; set; }
public int fk_idTypeItemIMCaracteristicsItems { get; set; }
public byte[] typeValueCaracteristicItem { get; set; }
public virtual ICollection<imvaluesofitemscaracteristic> imvaluesofitemscaracteristics { get; set; }
public virtual imtypeitems imtypeitem { get; set; }
}
所以我有两个模特:
public partial class imtypeitems
{
public imtypeitems()
{
this.imcharacteristicsitems = new HashSet<imcharacteristicsitem>();
this.imitems = new HashSet<imitem>();
}
public int idTypeItem { get; set; }
public string DesignationTypeItem { get; set; }
public byte[] SymbolTypeItem { get; set; }
public Nullable<int> MaxNumberConnectionsTypeItem { get; set; }
public virtual ICollection<imcharacteristicsitem> imcharacteristicsitems { get; set; }
public virtual ICollection<imitem> imitems { get; set; }
}
和
public static T UpadateRowInModel<T>(DbContext Model, string NameiD, int IdSelected, string NameFk_key ,int fk_key, IList<PropertyInfo> propertiesModel, IList<PropertyInfo> propertiesView, VMCaracteristicType vm) where T : class
{
T item = Model.Set<T>().Find(IdSelected);
foreach (var property in propertiesModel)
{
if (propertiesView.Count != 0)
{
property.SetValue(item, propertiesView.FirstOrDefault(elem => elem.Name.Equals(property.Name)) == null ? null :
propertiesView.FirstOrDefault(elem => elem.Name.Equals(property.Name)).GetValue(vm));
}
if (property.Name == NameiD)
{
property.SetValue(item, IdSelected);
}
if (property.Name == NameFk_key)
{
property.SetValue(item, null);
Model.Entry(item).Property(NameFk_key).IsModified = false;
}
}
return item;
}
,通用方法是:
public virtual ICollection<imcharacteristicsitem> imcharacteristicsitems { get; set; }
编辑: 所以我意识到问题是实体框架无法保存,因为我的表imtypeitems有一个caractéristique的集合
var RowBeforupdate = ImItemsModel.imcharacteristicsitems.Include("imtypeitem").Single(row => row.idCharacteristicItem == idCaracteristiqueSelected);
var UpdateCaracteristicTypeItem = StaticGenericUpdate.UpadateRowInModel<imcharacteristicsitem>(ImItemsModel, "idCharacteristicItem", idCaracteristiqueSelected, "fk_idTypeItemIMCaracteristicsItems", fk_value, propertiesForModel, propertiesForView, this);
ImItemsModel.Entry(RowBeforupdate).CurrentValues.SetValues(UpdateCaracteristicTypeItem);
所以我必须删除我希望从此表更新它的行,之后我将保存,所以我不能删除集合的行我尝试这样:
{{1}}
只是一个ps:我不是实体框架的专家:(
答案 0 :(得分:0)
FK null异常的最可能原因是在FK_ID属性之后的foreach
循环中处理/设置FK实体属性。因此,即使您将FK_ID IsModified
值更改为false
,您最有可能在以后将imtypeitem
属性设置为null。
您还要根据视图属性更改所有模型属性;因此,如果没有特定的视图属性,您将设置模型属性为null。在这种情况下,这很少是您想要做的事情。通常,您只想更改相应的视图属性,并保持其他模型属性不变。
因此,泛型方法的foreach
部分应如下所示:
if (propertiesView.FirstOrDefault(elem => elem.Name.Equals(property.Name)) != null)
{
property.SetValue(item, propertiesView.First(elem => elem.Name.Equals(property.Name)).GetValue(vm));
}
如果某些属性属于视图属性但您不希望更新它们,则可以跳过它们(使用Nameid
和NameFk_key
):
if(property.Name == NameiD || property.Name == NameFk_key)
continue;
因此泛型方法的最终形式可能如下所示:
public static T UpadateRowInModel<T>(DbContext Model, string NameiD, int IdSelected, string NameFk_key ,int fk_key, IList<PropertyInfo> propertiesModel, IList<PropertyInfo> propertiesView, VMCaracteristicType vm) where T : class
{
T item = Model.Set<T>().Find(IdSelected);
foreach (var property in propertiesModel)
{
if(property.Name == NameiD || property.Name == NameFk_key)
continue;
var viewP = propertiesView.FirstOrDefault(elem => elem.Name.Equals(property.Name));
if (viewP != null)
{
property.SetValue(item, viewP.GetValue(vm));
}
}
return item;
}
在foreach
上执行propertiesView
的情况下,您也可以进行变更;也可以调整方法的参数。
旁注:我不确定是否
var LineModified = (from x in ImItemsModel.imtypeitems select x.imcharacteristicsitems).ToList();
LineModified.ForEach(p => ImItemsModel.Entry(p).State = System.Data.Entity.EntityState.Modified);
做一些有用的事情,或者它做了什么。 lambda中的p
是enity类型的ICollection
,而不是单独的DB上下文实体。更不用说您想为Modified
类型的所有实体设置imcharacteristicsitem
状态。也许你可以解释一下这个原因。