实体框架POCO与外键 [英] Entity Framework POCO with Foreign keys

查看:149
本文介绍了实体框架POCO与外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题可以通过示例代码更好地解释。我正在使用POCO,默认情况下由C#POCO生成器生成的更改跟踪代理。请参见下文。

My question can better be explained via example code. I am using POCO with change tracking proxies that is generated by the C# POCO generator by default. Please see below.

假设您在数据库中有Movie,MusicDirector和Director,并且它们之间的关系是Director& MusicDirector可以直接播放多部电影,而影片只能有一个导演和MusicDirector。由于我是一个新的用户,不能发布图像,这里是我的数据库结构。

Assume you have Movie, MusicDirector and Director in the database and the relationship between them is a Director & MusicDirector can direct multiple movies and a movie can have only one Director and MusicDirector. Since I am a new user and cannot post images, here is my db structure.

电影表有MovieId,Name,MusicDirectorId,DirectorId

Movie table has MovieId, Name,MusicDirectorId,DirectorId

Director表有DirectorId,Name

Director table has DirectorId, Name

MusicDirector表有MusicDirectorId,Name

MusicDirector table has MusicDirectorId, Name

这是图表的链接。 http://i.stack.imgur.com/ce49r.png

我试图插入一个新的电影,导演和音乐导演已经存在在数据库中。以下是我的代码

I am trying to insert a new movie and the director and musicdirector "already exists" in the db. Below is my code.

Movie movie = new Movie();            
        movie.Name = "Movie1";
        movie.Director = new Director() { Name = "DirectorA" };           
        movie.MusicDirector = new MusicDirector() { Name = "MusicDirectorA" };

        using (TestEFEntities ctx = new TestEFEntities())
        {
            movie.Director = ctx.Directors.Where(x => x.Name == movie.Director.Name).FirstOrDefault();
            movie.MusicDirector = ctx.MusicDirectors.Where(x => x.Name == movie.MusicDirector.Name).FirstOrDefault();                                    
            ctx.Movies.AddObject(movie);                    
            ctx.SaveChanges();
        }

现在,当我这样做,MusicDirector记录再次添加,即使它被覆盖通过db的记录。你可能会认为我为什么要保留这行电影.Director = new Director(){Name =DirectorA};最初,它是一个Asp.net MVC应用程序,其中Movie对象与用户添加的导演和musicdirector名称绑定。所以,前四行是由MVC隐含地完成的,并且认为所有其他行都在服务层中。我缺少一些东西,因为这是一个非常基本的场景,框架应该处理它?当然,解决这个问题的一个办法是创建一个新的Movie对象,并从db中分配我不想做的记录,因为我必须从控制器发送的电影对象中复制所有的属性。如何解决这个问题?

Now when I do this, MusicDirector record is added again even though it is overwritten by the record from the db. You may think why I am keeping this line movie.Director = new Director() { Name = "DirectorA" }; initially, it is an Asp.net MVC app where Movie object is bound with the director and musicdirector names the user adds. So, the first 4 lines are done implicitly by MVC and think all the other lines are in the service layer. Am I missing something as this is a very basic scenario and the framework should handle it? Of course, one solution to correct this problem is to create a new Movie object and assign the records from db which I don't want to do as I have to copy all the properties from the movie object sent by controller. How can I solve this problem?

此外,在自我跟踪实体中也可以正常工作。这是POCO的某种限制,如果有人可以解释这个行为,会很棒吗?

Also this works correctly in Self-Tracking Entities. Is this some kind of a limitation to POCO and it would be great if someone can explain the behavior?

推荐答案

如果您使用POCO,那么您的代码应该按照您的期望工作。或者,您可以尝试填充FK而不是像这样分配整个对象:

If you are using POCOs, then your code should work as the way you expected. Alternatively, you can try to populated the FKs instead of assigning the whole object like this:

using (TestEFEntities ctx = new TestEFEntities())
{
    movie.DirectorID = ctx.Directors
        .Where(x => x.Name == movie.Director.Name).First().DirectorID;

    movie.MusicDirectorID = ctx.MusicDirectors
        .Where(x => x.Name == movie.MusicDirector.Name).First().MusicDirectorID;

    ctx.Movies.AddObject(movie);                    
    ctx.SaveChanges();
}

这篇关于实体框架POCO与外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆