【发布时间】:2017-11-07 18:55:22
【问题描述】:
我有一个具有以下模型和一对多关系的 EF Core Db
public class AttributeType
{
public int AttributeTypeId { get; set; }
public string Name { get; set; }
public List<Attribute> AttributeList { get; set; }
}
public class Attribute
{
public int AttributeId { get; set; }
public string Name { get; set; }
public int AttributeTypeId { get; set; }
public AttributeType AttributeType { get; set; }
}
如果我尝试以这种方式添加属性,它会起作用:
using (var db = new SampleDbContext())
{
var attributeType = db.AttributeTypes.FirstOrDefault();
Attribute attribute = new Attribute
{
Name = "bbb",
AttributeTypeId = attributeType.AttributeTypeId,
AttributeType = attributeType
};
var item = db.Attributes.Add(attribute);
db.SaveChanges();
}
(实际上,attributeType 将来自组合框,名称来自文本框,但现在让我们保持代码简单)
但是当我尝试使用通用方法时,如以下代码,不起作用
AttributeType attributeType;
using (var db = new SampleDbContext())
{
attributeType = db.AttributeTypes.FirstOrDefault();
}
Attribute attribute = new Attribute
{
Name = "eee",
AttributeType = attributeType,
AttributeTypeId = attributeType.AttributeTypeId
};
DbService.Insert(attribute);
public static bool Insert<T>(T item) where T : class
{
try
{
using (var db = new SampleDbContext())
{
db.Add(item);
db.SaveChanges();
}
return true;
}
catch (Exception exception)
{
Debug.WriteLine($"DbService Insert Exception: {exception}");
return false;
}
我得到以下异常
抛出异常:Microsoft.EntityFrameworkCore.dll 中的“Microsoft.EntityFrameworkCore.DbUpdateException” DbService 插入异常:Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 ---> Microsoft.Data.Sqlite.SqliteException:SQLite 错误 19:“唯一约束失败:AttributeTypes.AttributeTypeId”。 在 Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC(Int32 rc,Sqlite3Handle db) 在 Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior 行为) 在 Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection 连接,字符串 executeMethod,IReadOnlyDictionary
2 parameterValues, Boolean closeConnection) at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary2 参数值) 在 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection 连接) --- 内部异常堆栈跟踪结束 --- 在 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection 连接) 在 Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Tuple2 parameters) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList1 entriesToSave) 在 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(布尔型 acceptAllChangesOnSuccess) 在 Microsoft.EntityFrameworkCore.DbContext.SaveChanges(布尔型 acceptAllChangesOnSuccess) 在 UwpSamples.Services.DbService.Insert[T](T 项)
但是如果我没有传递 AttributeType 或者我将它设置为 null,就像下面的代码一样,它可以工作:
AttributeType attributeType;
using (var db = new SampleDbContext())
{
attributeType = db.AttributeTypes.FirstOrDefault();
}
Attribute attribute = new Attribute
{
Name = "ddd",
AttributeType = null,
AttributeTypeId = attributeType.AttributeTypeId
};
DbService.Insert(attribute);
-
AttributeType attributeType;
using (var db = new SampleDbContext())
{
attributeType = db.AttributeTypes.FirstOrDefault();
}
Attribute attribute = new Attribute
{
Name = "ddd",
AttributeTypeId = attributeType.AttributeTypeId
};
DbService.Insert(attribute);
谢谢
【问题讨论】:
-
我很困惑 - 您问题中的最后两个代码块与您失败的代码块完全相同,但您说它在这些情况下有效?
-
我认为这与 EF 无法确定项目应该去哪里的事实有关。我建议将您的
List<>类型更改为ICollection<>并将该属性设为virtual。这将允许 EF 使用其HashSet<>类型作为ICollection<>的实现,然后它可以跟踪子元素的“父”ID。但是,这可能在 EF 核心中发生了变化... -
不要将通用存储库与 EF 一起使用 - 它不适合包含相关实体(简单或集合)的实体。例如
Add方法将尝试添加实体和所有相关数据。 -
@RobertPetz 对不起,你是对的,该死的副本和过去,已修复。谢谢!
-
@MichaelCoxon 有意思,我试试,谢谢
标签: c# uwp entity-framework-core