gpt4 book ai didi

entity-framework-4 - Entity Framework -当父记录已经存在时在子表中插入记录

转载 作者:行者123 更新时间:2023-12-04 04:08:23 25 4
gpt4 key购买 nike

下午好-

我正在使用LINQ to Entity Framework开发用于数据访问层的Silverlight应用程序。我的n层数据库模型包含约30个左右的表,并且始终具有许多多层父子关系。最近开始编写我的数据服务和单元测试,并发现在已经定义了父表记录时将新记录插入子表的问题。这是我的父表和子表的简化版:

家长表:

用户数
用户ID(PK)
电子邮件
密码
等等...

child table :

用户资料
UserProfileID(PK)
各种个人资料信息...
用户ID(FK-用户表)

因此,在这一点上,我已经使用 Entity Framework 为ORM创建各种类,并且希望为实体上的CRUD操作创建数据服务。以下是我的用于插入新User(没有父表引用)的方法的示例代码:

    public User CreateUser(User newUser)
{
using (var _context = new ProjectDatabase())
{
newUser.CreatedDate = DateTime.Now;
newUser.ModifiedDate = DateTime.Now;
_context.AddToUsers(newUser);
_context.SaveChanges();
}

return newUser;
}

这样很好。我已经为此编写了单元测试,没问题。现在,另一方面,考虑为将新的UserProfile对象插入数据库而编写的以下数据服务方法。首先,我有一个非常相似的数据服务:
    public UserProfile CreateProfile(UserProfile newUserProfile)
{
using (var _context = new ProjectDatabase())
{
newUserProfile.CreatedDate = DateTime.Now;
newUserProfile.ModifiedDate = DateTime.Now;
_context.AddToUserProfiles(newUserProfile);
_context.SaveChanges();
}

return newUserProfile;
}

此代码与其他代码一样,可以毫无问题地进行编译。但是,我的单元测试始终失败。这是我的单元测试的代码:
    [TestMethod]
public void UserProfileCrudTest()
{
IProfileDataService _dataService = new ProfileDataService();

// Pre-seeded data on a State for foreign key
State _myState;
using (var _context = new ProjectDatabase())
{
_myState = _context.States.First();
}

// Creating temporary User for association with new UserProfile
User _myUser = new User()
{
Email = "test",
Password = "test",
IsActive = true,
NameFirst = "test",
NameLast = "test"
};

_myUser = _dataService.CreateUser(_myUser);
Assert.IsNotNull(_myUser);

// Attempt to create new UserProfile, assigning foreign key
_myUserProfile = new UserProfile()
{
Address = "123 Main",
City = "Anywhere",
State = _myState,
PostalCode = "63021",
UserID = _myUser.UserID
};

// This call to CreateProfile throws an exception and the test fails!!
_myUserProfile = _dataService.CreateProfile(_myUserProfile);
Assert.IsNotNull(_myUserProfile);

// Remaining test code... never gets this far...
}

因此,在这一点上,我的单​​元测试引发了以下异常:

测试方法MyProject.DataServices.Tests.SecurityTests.UserProfileCrudTest引发了异常:
System.InvalidOperationException:仅当该属性的当前值为null时,才可以设置EntityKey属性。

从到目前为止的研究中可以了解到,这某种程度上又与导航属性有关,该属性将新的UserProfile对象与父表/对象上的User.UserProfiles集合相关联。但是我不确定要解决此问题需要采取什么步骤。我是否需要以某种方式将父项附加到ObjectContext?任何帮助将不胜感激!

谢谢,
杰夫·S。

最佳答案

您不需要做所有这些事情。使用EF 4.0,您的代码可以像这样简单:

public UserProfile Create(UserProfile userProfile) {
using (var context = new ProjectDatabase()) {
//add the new graph to the context:
context.UserProfiles.AddObject(userProfile);
context.SaveChanges();
}
return userProfile;
}

public void UserProfileCrudTest() {
User _myUser = new User() {
Email = "test",
...
};
UserProfile _myUserProfile = new UserProfile() {
Address = "123 Main",
...
};

// join the new UserProfile to the User
_myUserProfile.User = _myUser;
UserProfile userProfile = Create(_myUserProfile);
}

解释:

在典型的数据访问方案中,您所做的事情很有意义,在这种情况下,您必须首先插入新的User,检索其UserID,然后使用该ID插入新的UserProfile。但是, SaveChanges 会为您完成所有这些操作
是新的,并且它们是相关的。它还使用模型的映射来找出
是从属实体(在这种情况下为UserProfile),并且需要外键(UserID)。
利用此信息,它将以正确的顺序执行数据库插入。

向现有用户添加新的UserProfile:

如果要向现有用户添加新的UserProfile,并且已经有要向其添加配置文件的User对象,则可以通过编写以下内容来关联它们:
userProfile.User = yourUserObject
// OR
yourUserObject.UserProfiles.add(userProfile)

然后调用SavingChanges()。

如果只有UserID,则可以像UserProfile.UserID = userID一样进行设置。顺便说一句,我知道这是您最初尝试执行的操作,但是您遇到了一个异常(exception),因此这是您需要执行的操作:

1.从数据库更新模型,以确保模型与数据库完全同步。

2.逐步执行代码,并确保为UserProfile对象(用户表中确实存在的用户)设置了合法的UserID-您甚至可以尝试对其进行硬编码。

3.再次运行它,如果您仍然遇到异常,则请发布您的堆栈跟踪信息,因为我运行了您的代码,但没有得到任何信息,因此您的异常可能来自一个完全不同的问题。

关于entity-framework-4 - Entity Framework -当父记录已经存在时在子表中插入记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3579230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com