【问题标题】:How EF will get the system generated ID of a newly added objectEF 如何获取系统生成的新添加对象的 ID
【发布时间】:2015-07-31 11:07:31
【问题描述】:

我正在开发一个 asp.net mvc5 Web 应用程序 + 我正在使用 EF6.0。有时我无法理解 EF 如何在内部处理事情。例如,我有两个实体命名;技术和机架。其中Technology.TechnologyID 是系统生成的ID,而Rack.RackID 是用户定义的密钥,将=Technology.TechnologyID.。所以我有以下方法来添加新技术,然后添加新机架并分配Rack.RackID 等于系统生成的Technology.TechnologyID

    Technology technology = new Technology
                    {
                        IsCompleted = false,
                        IsDeleted = true,
                        TypeID = technologyypeID,
                        Tag = "CAB" + max.ToString(),
                        PartialTag = max,
                        StartDate = DateTime.Now,
                        IT360ID = dbresource.RESOURCEID,//,,
                        IsManaged = rj.Technology == null ? true : rj.Technology.IsManaged


                    };



                    rj.Rack.RackID = technology.TechnologyID;
SAVE():

现在开始时我虽然上面的我不起作用,因为当我尝试时:-

rj.Rack.RackID = technology.TechnologyID;

此时 TechnologyID 将不可用,并且使用 VS 我发现在运行时 TechnologyID 将等于零:-

所以我不确定 EF 如何处理这个问题?并且它强制 Rack.RackID 等于 Technology.TechnologyID ,尽管在运行时技术 ID 将为零。这是从 sql profiler 生成的 sql 语句:-

exec sp_executesql N'insert [dbo].[Racks]([RackID], [DataCenterID], [ZoneID], [IT360SiteID])
values (@0, @1, @2, @3)
select [timestamp]
from [dbo].[Racks]
where @@ROWCOUNT > 0 and [RackID] = @0',N'@0 int,@1 int,@2 int,@3 bigint',@0=128,@1=3,@2=2,@3=4 

不确定128 在运行时是如何分配的,尽管值为零?

【问题讨论】:

  • EF 很可能知道这些关系,因此如果您通过普通对象引用属性链接了对象,EF 知道在将父对象插入数据库后从何处检索 ID。
  • @LasseV.Karlsen 你能在这方面提供更多建议吗?虽然这是 EF 的一个很棒的特性,但它是如何发生这种神奇的完全令人困惑?
  • 不,我不能,我没有足够的 EF 经验,这只是一个想法,其他人将不得不验证它或说我错了(已知偶尔发生:))

标签: c# asp.net sql-server entity-framework entity-framework-6


【解决方案1】:

您创建了一个新的Technology 对象,它的TechnologyID 是数据库生成的。当它被插入时,EF 在插入之后带有一个选择来检索生成的值。像这样的:

DECLARE @TechnologyID int
SELECT @TechnologyID = [TechnologyID]
FROM [dbo].[Technology]
WHERE @@ROWCOUNT > 0 AND [TechnologyID] = scope_identity()

然后,Entity Framework 使用结果来修复Technology 实体,这样当您插入Rack 对象时,其RackID(不是数据库生成的)被正确设置为新的@ 987654327@(如您在代码中指定的那样)。在Racks 表上发出选择以检索时间戳时使用的@0 参数也设置为新值(在您的示例中为128)。

【讨论】:

    【解决方案2】:

    当您分配rj.Rack.RackID = technology.TechnologyID; 时,您的新technology 对象尚未提交到数据库,因此不会有分配的TechnologyID 属性。在不更改映射/架构的情况下,解决问题的最简单方法是保存一次以提交 technology 并将其分配为 TechnologyID,将其分配为您的 RackID,然后再次保存。

    更长、更合适的解决方案是让RackID 成为一个实际的身份属性,而是使用从RackTechnology 的外键关系和适当的EF 映射。

    【讨论】:

    • 但正如我所说,我在当前代码中没有遇到任何问题,,,我试图了解 EF 如何处理这个魔法,,你读我的问题了吗,你说我需要首先保存我的技术对象以获取其 id....但我没有保存它,并且 EF 神奇地将 technologyid 分配给 RACK ...所以我的问题是这个魔术是如何发生的!!!!
    • 很抱歉投了反对票,因为您的回答与我的问题无关......&看来您和我一样感到困惑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多