实体数据模型:外键巧用

Categories: Other
Tags: No Tags
Comments: 18 Comments
Published on: 2010 年 08 月 23 日

[原文作者]:Yang Cao

[原文链接]:Entity Data Model: working with foreign key when you don’t have it

        概念模型中是否包含FK(外键)一列争议已久,因此Visual Studio 2010在创建实体数据模型的向导中添加了一个复选框。这样,是否使用外键由开发者自己去决定。昨天我做了一些有趣的事情,发现了外键在下面介绍的情况下有着突出的作用。

我的应用程序十分简单:将A中与Order相关的客户移到B中。

image

        如果FK(CustomerID)在Order这个 实体当中存在,我要做的,仅仅是针对外键建立一个查找绑定,然后调用dataContext.SaveChanges()。如何使用拖拽的方法在组合框组件上创建一个查找绑定?首先,将FK列(本例中Order实体的CustomerID列)拖拽到窗体上,与此同时将会生成一个组合框,然后将与之相关的查询表(Customer实体)拖拽到刚才生成的组合框上,这样之后,SelectedValue、SelectedValuePath,、ItemsSource和 DisplayMemeberPath等属性就会自动设置。

如果实体中并不存在FK列,事情将变得稍微麻烦一点。

Orders绑定到DataGrid

image

这个步骤很简单,只需要将Orders节点拖拽到WPF设计器上。

针对组合框创建一个查询绑定

        因为在这个模型中,我没有FK列,也就是说在Order实体中不存在CustomerID属性。为了创建一个查询绑定,我需要将Orders中的Customer实体展开,将CustomerID绑定到一个组合框上。

clip_image002

        当把这个节点拖拽到WPF设计器上之后,我就创建 了一个复合绑定。为了将它转换成一个查询绑定,我会将这个新创建的组合框链接到查询表上。为了达到这个目的,我们首先将Customers节点(上图中标记为2)拖拽到组合框上,你会注意到在这个过程中你的鼠标将会由“+”变成一个箭头,这表明我们并没有创建新的控件,而是使已有的控件根据拖拽上来的资源进行更新。

创建一个按钮保存修改

然后我会添加一个按钮“Update Customer”,在它的点击处理事件当中,我需要找到当前选中的order,获取新的CustomerID去替换之前的FK的值,保存修改:

Order currentOrder = (Order)ordersViewSource.View.CurrentItem;

string customerID = customerIDComboBox.SelectedValue.ToString();

currentOrder.CustomerReference.EntityKey.EntityKeyValues[0].Value = customerID;

northwindEntities.SaveChanges();

为了简化代码,在MainWindow类中,我将DataContext(northwindEntities)和CollectionViewSource(ordersViewSource)设置成属性。我需要在Order下,找到CustomerReference并且设置EntityKeyValue

F5

调试程序,一开始一切都进行的很顺利,但是当我在组合框中由一个customer切换到另一个时,弹出一个异常—- InvalidOperationException:CustomerID是对象键值信息的一部分,不允许修改。尽管我成功的创建了查询绑定,但是却不能修改它的值,因为SelectedValue不是Order的外键,而是Customer的主键!

这个异常提醒我,组合框应该绑定为OneWay模式。我在XAML文件中找到组合框,更新了SelectedValue的绑定模式:

SelectedValue="{Binding Path=Customer.CustomerID,Mode=OneWay}"

再次F5

现在改变组合框中的选项不会再弹出刚才的异常。我点击“Update Customer”按钮继续测试,出现另一个异常:EntityKey一经设定,不能再做修改。我就不信办不到,我到网上开始搜索,然后发现,尽管EntityKey无法重新设置,但是实体的键值是可以的。现在我们对FK的值进行以下修改:

currentOrder.CustomerReference.EntityKey = new System.Data.EntityKey(currentOrder.CustomerReference.EntityKey.EntityContainerName+"."+currentOrder.CustomerReference.EntityKey.EntitySetName,"CustomerID", customerID);

如果你拥有的是一个复合键,你可以使用KeyValuePair。想要了解更多,请看这里

完成以上所有步骤,我的程序总算如所期望的那样工作了。也许你会问,为什么你不简单的在设计中包含外键,以避免这些不必要的额外代码和可能出现的异常?那我会告诉你,如我之前所说的,有些设计者,在概念模型中,并不倾向于包含FK列,因为FK是关系数据库中的概念。另一个原因是,包含FK的功能在Visual Studio 2010里新添加的表中才开始得应用,如果你有一个已存在的实体数据模型,那么你始终得习惯没有FK的生活。

如果你有什么想法或是问题,我将会很高兴与你共同讨论。

谢谢!

18 Comments - Leave a comment
  1. Thank you for posting this, It’s just what I was browsing on bing. I’d very much rather hear opinions from an individual, rather than a corporate web page, that’s why I like blogs so much. Thanks!. Just bookmarked your site! I’ll be back to check out your future postings. A shapely Added Agreeable.

  2. TY a ton for posting, it was very informative and helped tons.. TY a ton for posting, it was very informative and helped tons. : ) Additional Added.

  3. Such a usefule blog wow !!!!. you’ve gotten an ideal blog right here! would you prefer to make some invite posts on my blog? A shapely A shapely.

  4. Love the post, thanks keep up the good work! Bookmarked!. Your blog is so informative keep up the good work!!!! more please awesome ;).

  5. Thanks! Will probably be nice to anyone who usess it, including myself. Sustain the nice work for positive i’ll take a look at extra posts.. My sis advised me about your site and how great it is. She’s right, I’m really impressed with the writing and slick design. awesome ;) ;).

  6. I Really enjoyed your blog. I just bookmarked it. I am a regular visitor of your website I will share It with Yep. I lurk there often. You guys have a wonderful blog. Keep up the good work.. This is probably one of the best mentions of this topic I’ve seen in quite a while. It’s obvious that your knowledge of the subject is deep and this made for a very interesting read. pleasing awesome terrific.

  7. TY a ton for posting, it was very informative and helped tons.. This is probably one of the best mentions of this topic I’ve seen in quite a while. It’s obvious that your knowledge of the subject is deep and this made for a very interesting read. pleasing fantastic tremendous.

  8. It’s hard to find knowledgeable individuals on this matter, but you sound like you already know what you’re talking about! Thanks. I Really enjoyed your blog. I just bookmarked it. I am a regular visitor of your website I will share It with Yep. I lurk there often. You guys have a wonderful blog. Keep up the good work. :) fantastic terrific.

  9. TY a ton for posting, it was very informative and helped tons.. What made you think about such a topic. Its funny I am not the only one that feels that way about it. Keep it up! fantastic great fantastic.

  10. I don’t usually reply to posts but I will in this case. WoW. Hello webmaster I like your post. outstanding tremendous great.

  11. you’ve gotten an ideal blog right here! would you prefer to make some invite posts on my blog?. Just bookmarked your site! I’ll be back to check out your future postings. ;) ;) :).

  12. Big 4 Guru说道:

    I really loved the post so I used my Digg account to digg it.. i bookmarked this! looking for updates. terrific more please awesome.

  13. The personal nature of the blog is what I find appealing.

  14. It’s hard to find knowledgeable individuals on this matter, but you sound like you already know what you’re talking about! Thanks. amazing stuff thanx :) terrific great.

  15. Hey! This is really cool, exactly what I was looking for. The designs here are so fabulous!. Thanks for uploading this stuff.

  16. Thersa Schwander说道:

    I have been examinating out some of your articles and it’s pretty nice stuff. I will definitely bookmark your site.

  17. Flossie Novelly说道:

    This page appears to get a good ammount of visitors. How do you promote it? It offers a nice unique spin on things. I guess having something authentic or substantial to post about is the most important factor.

Leave a comment


Welcome , today is 星期六, 2017 年 02 月 25 日