【问题标题】:Is this correct way to update Many to One relationship with Entity Framework (.NET 3.5)?这是更新与实体框架(.NET 3.5)的多对一关系的正确方法吗?
【发布时间】:2012-02-03 16:56:40
【问题描述】:

您知道,我正在使用:Visual Studio 2008、.NET 3.5

Campaign 与 Campaign_Url 是多对一的关系, 因此多个广告系列可以共享同一个 Campaign_Url。

如你所见,代码如下:

我从具有 SelectedCampaignID 的上下文中找到 Campaign 实体

            Campaign aCampagin = (from c in context.Campaign
                                  where c.campaign_id == SelectedCampaignID
                                  select c).First();

使用 SelectedCampaignUrlID 从上下文中查找选定的 Campaign_Url 实体

            CampaignUrl aCampaign_Url = (from c_url in context.CampaignUrlSet
                                         where c_url.campaigin_url_id == SelectedCampaignUrlID
                                         select c_url).First();

将 CampaignUrl 实体分配给 Campaign 实体

            aCampagin.Campaign_Url = aCampaign_Url;
            context.SaveChanges();

但在数据库中,Campaign 表有一个 url_id 列,该列具有与 CampaignUrl 表的 CampaignUrlID 列的前键。

如果我使用普通 SQL 进行更新,我会

UPDATE Campaign SET url_id  = SelectedCampaignUrlID WHERE Campaign_ID = SelectedCampaignID;

所以它会避免搜索 CampaignUrl 实体。

我不相信我的做法是正确的......使用实体框架进行此更新的正确方法是什么?


编辑:包括我试图通过 ID 更改的案例。

            Campaign aCampagin = (from c in context.Campaign.Include("Campaign_Url")
                                  where c.campaign_id == cam.campaign_id
                                  select c).First();
            aCampagin.Campaign_Url.campaigin_url_id = SelectedCampaignUrlID.Value;
            context.SaveChanges();

报错:

属性“campaigin_url_id”是对象键的一部分 信息,不能修改。

【问题讨论】:

    标签: c# .net visual-studio-2008 entity-framework


    【解决方案1】:

    .NET 3.5 中的实体框架不允许您直接设置外键。

    见第二个例子here

    我认为你需要这样做:

    EntityKey campaignUrlId = 
        new EntityKey("Context.CampaignUrlSet", "campaign_url_id", SelectedCampaignUrlId);
    

    那么您应该能够通过键而不是实体来访问关系。

    詹姆斯的回答也不错。

    编辑:

    看到这个问题:Entity Framework: Setting a Foreign Key Property

    【讨论】:

    • 谢谢,它成功了~ 不知道它应该是 new EntityKey("EntityContainerName.EntityName") 这就是为什么我不断获取标识符“Context” is missing execption lol ...
    【解决方案2】:

    长而短的回答,是的,或者至少这是我使用实体框架的方式。虽然我可能会这样处理:

    Campaign aCampagin = (from c in context.Campaign
                          where c.campaign_id == SelectedCampaignID
                          select c).First();
    
    aCampagin.Campaign_URL = (from c_url in context.CampaignUrlSet
                              where c_url.campaigin_url_id == SelectedCampaignUrlID
                              select c_url).First();
    
    context.SaveChanges();
    

    实体框架处理您发布的 SQL 查询。

    【讨论】:

    • 是的,因为 context.Campaign_UrlSet 是完整的 CampaignUrl 集。如果您需要为广告系列分配一个新的 Campaign_URL,您可以:Campaign_URL aCampaign_URL = new Campaign_URL(); aCampagin.Campaign_URL = aCampaign_URL;aCampaign_URL 的 Id 属性将为 0,直到您调用 context.SaveChanges
    • 因此,在实体框架中使用 Id 的一个问题是,您可能会提取自上次保存更改以来添加到 Campaign_Urls 的所有实体,并且您不一定知道要分配的对象。
    【解决方案3】:

    在 EF 中直接更改 id 就可以了。

    或者您可以从其 Campaign_Url 中分离()活动,然后将其附加()到另一个。

    (从技术上讲,您可以将其从 Campaign_Url.Campaigns 或任何用于广告系列列表的属性中分离出来)。

    编辑:好的,这已经得到了回答,但没有一个答案(包括我的)实际上涵盖了我的想法,所以我要再试一次:

    代替

     aCampagin.Campaign_Url = aCampaign_Url;
    

    我相信他们打算让你做的事情是这样的:

    aCampagin.Campaign_Url.Campaigns.Remove(aCampaign);
    aCampaign_Url.Campaigns.Add(aCampaign);
    

    我在我的 EF 项目中测试了类似的东西,尽管它是 EF4。

    【讨论】:

    • 我试过了,但它给了我错误“属性 'campaigin_url_id' 是对象的关键信息的一部分,无法修改。”所以这只适用于 4.0?
    • @KingChan -- 是的,我认为这是 4.0 中的新内容。查看我的答案和我链接的相关问题。
    • 嗯。没有意识到这不再起作用了。我会把它归档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    相关资源
    最近更新 更多