Entity framework 4 如何在自跟踪实体中使用辅助密钥?

Entity framework 4 如何在自跟踪实体中使用辅助密钥?,entity-framework-4,self-tracking-entities,Entity Framework 4,Self Tracking Entities,在使用自跟踪实体和实体框架4时,我试图建立一个使用次键的良好实践,但似乎存在很多陷阱 假设我有一个报警实体,它可以向用户提供ConfirmingUser导航属性。用户的Id作为主键,登录名作为辅助键。 在我的系统中的某个时刻,我将一个新的用户实体分配给报警的确认器。在这一点上,我只知道用户的登录次要密钥,假设它是一个n层架构,在这一点上查找Id是不切实际的。 报警随后被传输到持久层,该持久层将尝试存储报警。 现在是棘手的部分。我需要确定数据库中是否已经存在ConfirmingUser,并采取适当

在使用自跟踪实体和实体框架4时,我试图建立一个使用次键的良好实践,但似乎存在很多陷阱

假设我有一个报警实体,它可以向用户提供ConfirmingUser导航属性。用户的Id作为主键,登录名作为辅助键。 在我的系统中的某个时刻,我将一个新的用户实体分配给报警的确认器。在这一点上,我只知道用户的登录次要密钥,假设它是一个n层架构,在这一点上查找Id是不切实际的。 报警随后被传输到持久层,该持久层将尝试存储报警。 现在是棘手的部分。我需要确定数据库中是否已经存在ConfirmingUser,并采取适当的措施

我现在就是这样做的:

        using (var context = new PantoTestEntities())
        {
            if (alarm.ConfirmingUser != null && alarm.ConfirmingUser.ChangeTracker.State == ObjectState.Added)
            {
                var userIdQuery = from user in context.Users
                                  where user.Login == alarm.ConfirmingUser.Login
                                  select user.Id;
                if (userIdQuery.Any())
                {
                    // Disable cache or ApplyChanges will throw an exception, because the user already exists.
                    context.Alarms.MergeOption = MergeOption.NoTracking;

                    alarm.ConfirmingUser.Id = userIdQuery.First();

                    alarm.ConfirmingUser.MarkAsModified();
                }
            }

            context.Alarms.ApplyChanges(alarm);

            context.SaveChanges();

            // Accept changes in the full entity graph
            alarm.AcceptAllChanges();
        }
这种模式在我看来相当丑陋和低效。是否有更好的方法处理具有外部键的实体

上述代码中一个有趣的陷阱是不可能用具有相同登录名的新用户替换ConfirmingUser。也就是说,当客户端应用程序想要为报警分配ConfirmingUser时,它必须检查ConfirmingUser是否已分配给具有相同登录属性的用户。 原因是自跟踪实体的ApplyChanges将尝试将原始用户和新用户复制到EF上下文中,但EF不允许原始值和新值都是同一个实体,为什么它不能处理,这对我来说没有意义