在我的数据模型中,我的对象/表/数据之间存在相当普遍的区别:
因此,例如,我可能有一个User(事务)实体和一个UserType(数据字典)实体。
我希望(硬)将对数据字典实体实例的引用编码到我的代码中。这使我能够使用易于理解的语言对业务逻辑进行编码。 (例如,我可能有一个UserType为“Plain”,UserType为“Admin”,然后是一个规则,“只有当User的UserType等于Admin时才允许访问”。)
我正在使用LINQ-to-Entities作为我的数据访问技术/ ORM。为了实现数据字典引用,我正在存储EntityKeys。我的理解是它们与对象上下文分离,因此适用于此目的。 (因为它们不包含实体状态,所以我也不必担心该状态会过时。)
但是,当我尝试使用DD-EntityKey-reference添加新的事务实体时,这给了我一些问题。继续我的例子,我这样做:
UserEntities userEntities = new UserEntitites()
User user = new User()
user.UserType = new UserType()
user.UserType.EntityKey = adminEntityKey
userEntities.AddToUser(user)
...这给了我以下错误:
System.InvalidOperationException:无法将对象添加到ObjectStateManager,因为它已具有EntityKey。使用ObjectContext.Attach附加具有现有密钥的对象。
如果我尝试调用userEntities.Attach(用户)而不是AddToUser,我会得到这个:
System.InvalidOperationException:具有null EntityKey值的对象无法附加到对象上下文。
考虑到我正在做的新实体和预先存在的实体的混合,这两个错误都有意义。我不确定的是如何解决这个问题。有没有什么方法可以对DD实体进行分离引用并将它们分配给新的附加对象,而不需要我加载整个DD实体状态?
答案 0 :(得分:1)
我会试着解释你为什么会得到这些例外:
System.InvalidOperationException:无法将对象添加到ObjectStateManager,因为它已具有EntityKey。使用ObjectContext.Attach附加具有现有密钥的对象。
创建新用户和用户类型实体。 UserType上的EntityKey已设置,但是当您将其传递给userEntities.Add()时,EF会尝试将它们设置为ADDED状态。由于UserType具有EntityKey EF,因此意识到出现了错误并引发异常。
System.InvalidOperationException:具有null EntityKey值的对象无法附加到对象上下文。
在此异常中,UserType的一切正常,但抛出异常,因为User实体 - 它没有EntityKey,因此无法附加。
这就是我如何解决这个问题(如果你说的话,数据字典引用的硬编码还可以):
在UserType实体上,我将创建对UserType id的静态引用:
public partial class UserType
{
public const int AdminUserTypeID = 1;
public const int PlainUserTypeID = 2;
}
在用户实体上会有扩展程序属性,以便更轻松地访问UserType外键:
public partial class User
{
public int? UserTypeID
{
set
{
UserTypeReference.EntityKey = new EntityKey("UserEntities.UserType", "UserTypeID", value);
}
get
{
if (UserTypeReference.EntityKey == null)
return null;
if (UserTypeReference.EntityKey.EntityKeyValues.Count() > 0)
return (int)UserTypeReference.EntityKey.EntityKeyValues[0].Value;
else
return null;
}
}
}
最后,创建新用户的用例如下所示:
using(UserEntities userEntities = new UserEntitites())
{
User user = new User();
user.UserTypeID = UserType.AdminUserTypeID;
userEntities.AddToUser(user);
userEntities.SaveChanges()
}