1

实际上我花了一整天的时间在外键的 EntityFramework 上。假设我们有两个表。Process(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”。1 'LookupProcess' 是预期的。

我能问一下那个插入错误吗?那我的查询是否正确?

4

3 回答 3

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不理想,请参阅从 DbSet 3 表返回而没有错误“无法从查询中推断”,以获取使用嵌套实体执行此操作的示例。

对于你的第二个问题,这条线

p.LookupProcess = (from m in db.LookupProcessIds
    where descr = "example" select m).FirstOrDefault()

LookupProcessId以后可能会给您带来问题,因为如果没有process_description“示例”,您将获得null. 来自MSDN

引用类型和可空类型的默认值为空。

正因为如此,p.LookupProcess插入实体时如果为空,就会出现异常:

“AmpCUEngEntities.Processes”中的实体参与“FK_Process_LookupProcess”关系。找到 0 个相关的“LookupProcess”。1 'LookupProcess' 是预期的。

为了避免这种问题,您需要p.LookupProcess在它进入数据库之前检查它是否为空。

If Not p.LookupProcess Is Nothing Then 
    db.AddToProcesses(p)        
    db.SaveChanges()        
End If 
于 2012-10-15T10:36:18.270 回答
0

实际上,您错过了 DataEntityModel 及其框架中的一些概念。要操作数据,您必须从上下文的角度调用对象。这些允许您向 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()

我希望这将有所帮助。祝你今天过得愉快!

于 2012-10-12T14:11:13.037 回答
0

对于你的第一个问题:

 Dim result = (from x in db.Processes 
               where x.LookupProcess.descr = "example" 
               select x).FirstOrDefault()
于 2012-09-28T06:02:07.917 回答