【问题标题】:EF4: Save object childrenEF4:保存对象子项
【发布时间】:2011-05-24 18:46:51
【问题描述】:

在数据库中,我有这些表:Product、Request 和 RequestProducts。 RequestProducts 是将许多产品链接到一个请求的表。

这是我的代码:

        Product newProduct = new Product
                                 {
                                     Unity_ID = 3,
                                     Quantity = 2,
                                     Name = "toto",
                                     AlreadyCurrency = true
                                 };

        Request newRequest = new Request
                                 {
                                     User_ID = 1,
                                     CaseNumber = 1,
                                     Draft = false
                                 };

        newRequest.Products.Add(newProduct);

        _db.AddToProducts(newProduct);
        _db.AddToRequests(newRequest);
        _db.SaveChanges();

执行之后,在我的数据库中我得到 1 个产品和 1 个请求。没关系,但是使用 newRequest.Products.Add(newProduct); 行创建的链接并未创建表 RequestProducts 并且 EF4 通过向我提出请求对象中的 Products 列表来理解该链接。

是否可以仅使用此代码创建此链接?

谢谢!

【问题讨论】:

  • 根据您的 cmet 我的回答,我已经更新了。

标签: entity-framework-4 wcf-data-services


【解决方案1】:

一对多关系不需要额外的表。对于多对多关系,您只需要那个额外的表。

所以,在不知道你在做什么以及为什么做的更多细节的情况下,我会说它工作正常。

理想情况下,您的 Request 对象应如下所示:

public class Request
{
    public int RequestId {get; set;}
    //Other defining params here

    public ICollection<Product> Products {get; set;}
}

那么您的 Product 对象将如下所示:

public class Product
{
    public int ProductId {get; set;}
    //other defining params
    public int RequestId {get; set;} //your FK

    public virtual Request Request {get; set;} //If you ever need the Product to be aware of the Request to which it is attached.
}

【讨论】:

  • 哦,这是真的,我不需要这张额外的桌子!
【解决方案2】:

假设您使用生成的 EDMX 实体,您的 Product 表中应该有一个 RequestId FK 列。

那么在你从 DB 生成 EDMX 之后,就不会有额外的表了,所以你应该可以这样做:

Request newRequest = new Request
                         {
                             User_ID = 1,
                             CaseNumber = 1,
                             Draft = false
                         };

Product newProduct = new Product
                         {
                             Unity_ID = 3,
                             Quantity = 2,
                             Name = "toto",
                             AlreadyCurrency = true,
                             Request = newRequest
                         };


//Redundant
//newRequest.Products.Add(newProduct);

_db.AddToProducts(newProduct);

//Redundant
_db.AddToRequests(newRequest);

_db.SaveChanges();

//Never forget - or wrap in a using statement
_db.Dispose()

更新

  1. 上面的案例是one2many(一个请求有很多产品)
  2. 因为一旦我将Request(现在是Product 的一个属性)设置为newRequest,然后当我将它添加到上下文中(或者如果它已经添加),所有相关实体也会自动添加整个图表。
  3. 仔细阅读this

【讨论】:

  • @Shimmy:当我这样做时,我的 FK 中出现异常:ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_Product_Request] FOREIGN KEY([RequestID]) REFERENCES [dbo].[Request] ([ID]),而在我的上下文中,方法 Dispose() 不存在!
  • 你什么时候做什么?当您尝试更改数据库时?顺便说一句,作为一个好建议,我建议您使用diagrams,这将为您提供数据库的可视化模型——表和关系。为了您的方便,它也可以在 Visual Studio 中使用
  • @Shimmy:我已经更改了我的数据库和代码。现在我可以使用你的代码,但是我在你的SaveChanges() 上遇到了异常,是的,我使用图表但不在 Visual Studio 中,我在 SQL Server 中使用它
  • 您是否从数据库中重新生成了模型?转到您的 EDMX 设计器,右键单击表面并选择“从数据库生成模型”。如果您的模型反映了您的数据库并且您在创建模型时没有进行任何更改,那么您可以删除您的表,它们将重新生成并重新覆盖。顺便说一句,根据您的第一条评论,异常看起来很奇怪。看来您的数据库尚未修改。确保您保存了图表,然后从数据库重新生成模型,然后代码应该可以工作。
  • 关于Dispose,是ObjectContext的方法,看我更新的答案(第3号)。
猜你喜欢
  • 2011-10-19
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多