实际上,我花了整整一天时间在外键的EntityFramework上。 假设我们有两张桌子。 过程(APP_ID,PROCESS_ID) LookupProcessId(process_id,process_description)
你可以理解两个带有名字的表,第一个表,使用process_id来表示每个应用程序,描述在seoncd表中。 其实我多次尝试并弄清楚如何做查询:它就像
Dim result = (from x in db.Processes where x.LookupProcess is (from m in db.LookupProcessIds where descr = "example" select m).FirstOrDefault() select x).FirstOrDefault()
首先,我想问一下是否有更简单的方法。
其次我想问的问题是关于插入
p As New AmpApplication.CUEngData.Process
p.app_id=100
p.LookupProcess = (from m in db.LookupProcessIds where descr = "example" select m).FirstOrDefault()
db.AddToProcesses(p)
db.SaveChanges()
从外观看起来很好,但它给我错误说 'AmpCUEngEntities.Processes'中的实体参与'FK_Process_LookupProcess'关系。找到了0个相关的'LookupProcess'。预计会有'LookupProcess'。
我可以问是插错了吗?这是我的查询正确吗?答案 0 :(得分:0)
关于你的第一个问题:
Dim result = (from x in db.Processes
where x.LookupProcess.descr = "example"
select x).FirstOrDefault()
答案 1 :(得分:0)
实际上,您错过了DataEntityModel及其Framework的一些概念。要操纵数据,您必须从上下文的角度调用对象。这些允许您向ObjectStateManager指定DataObject的状态。在您的情况下,如果您具有来自FK的依赖数据,则必须从叶到根添加/更新任何链接数据。
此示例演示了简单(无依赖)数据操作。选择是否存在以及插入或更新。
如果您想了解有关ObjectStateManager操作的更多信息,请转至http://msdn.microsoft.com/en-us/library/bb156104.aspx
Dim context As New Processing_context 'deseign your context (this one is linked to a DB)
Dim pro = (From r In context.PROCESS
Where r.LOOKUPPROCESS.descr = LookupProcess.descr
Select r).FirstOrDefault()
If pro Is Nothing Then 'add a new one
pro = New context.PROCESS With {.AP_ID = "id", .PROCESS_ID = "p_id"}
context.PROCESS.Attach(pro)
context.ObjectStateManager.ChangeObjectState(pro, System.Data.EntityState.Added)
Else
'update data attibutes
pro.AP_ID = "id"
pro.PROCESS_ID = "p_id"
context.ObjectStateManager.ChangeObjectState(pro, System.Data.EntityState.Modified)
'context.PROCESS.Attach(pro)
End If
context.SaveChanges()
我希望这会有所帮助。祝你有愉快的一天!
答案 2 :(得分:0)
关于你的第一个问题,要扩展@jeroenh的建议:
Dim result = (from x in db.Processes.Include("LookupProcess")
where x.LookupProcess.descr = "example"
select x).FirstOrDefault()
Include
语句的添加将保留LookupProcess
个实体,以便您可以查询它们。如果没有Include
,x.LookupProcess
将为null,这可能会解释您为什么会遇到错误。
如果使用文字字符串作为Include
的参数并不理想,请参阅Returning from a DbSet 3 tables without the error "cannot be inferred from the query"以获取使用嵌套实体执行此操作的示例。
关于你的第二个问题,这一行
p.LookupProcess = (from m in db.LookupProcessIds
where descr = "example" select m).FirstOrDefault()
以后可能会导致您遇到问题,因为如果LookupProcessId
没有process_description
的“示例”,那么您将获得null
。来自MSDN:
reference和nullable类型的默认值为null。
因此,如果插入实体时p.LookupProcess
为null,则会出现异常:
'AmpCUEngEntities.Processes'中的实体参与'FK_Process_LookupProcess'关系。找到了0个相关的'LookupProcess'。预计会有'LookupProcess'。
为了避免这种问题,您需要检查p.LookupProcess
在进入数据库之前是否为空。
If Not p.LookupProcess Is Nothing Then
db.AddToProcesses(p)
db.SaveChanges()
End If