简体   繁体   中英

Entity Framework 6 Creating an single related record

I am using Entity Framework on a project involving TV Series. The data is loaded by loading Episode files. When I create an Episode it should find the series that it belongs to and use that one or else create a new one.

I am using an "EpisodeFactory" to create the Episodes and it works until I save and then it creates a new series for each episode.

I am looking for:

  • Series : Id = 01, Name = 'Gotham'
  • Episode : Id = 21, Name = 'GothamS01E01', Series = 01
  • Episode : Id = 22, Name = 'GothamS01E02', Series = 01

What I am Getting:

  • Series : Id = 01, Name = 'Gotham'
  • Series : Id = 02, Name = 'Gotham'
  • Series : Id = 03, Name = 'Gotham'
  • Episode : Id = 21, Name = 'GothamS01E01', Series = 02
  • Episode : Id = 22, Name = 'GothamS01E02', Series = 03

Here is my UnitTest for this:

    [Test]
    public void ShouldLoadSeriesIfOneExists()
    {
        const string testDirectory = TestContstants.TestDir + @"\ShouldLoadSeriesIfOneExists";
        var episodeFactory = new EpisodeFactory();
        var randomSeriesName = Guid.NewGuid().ToString();
        var testEpisodeA = episodeFactory.createNewEpisode(testDirectory + @"\" + randomSeriesName + @"S01E01.avi");
        var testEpisodeB = episodeFactory.createNewEpisode(testDirectory + @"\" + randomSeriesName + @"S02E03.avi");

        using (var dbContext = new MediaModelDBContext())
        {
            dbContext.Episodes.Add(testEpisodeA);
            dbContext.Episodes.Add(testEpisodeB);
            dbContext.SaveChanges();

            Assert.That(dbContext.Series.Count(s => s.SeriesName == randomSeriesName), Is.EqualTo(1));

            dbContext.Series.Remove(testEpisodeA.Series);
        }
    }

The EpisodeFactory get a file name and extracts the Episode information from the file.

The Series is fetched with:

    public Series GetSeriesBySeriesName(string seriesName)
    {
        using (var dbContext = new MediaModelDBContext())
        {
            if (dbContext.Series.Any())
            {
                var matchingSeries = dbContext.Series.FirstOrDefault(series => series.SeriesName == seriesName);
                if (matchingSeries != null) return matchingSeries;
            }

            var seriesByShowName = new Series(){SeriesName = seriesName};
            dbContext.Series.Add(seriesByShowName);
            dbContext.SaveChanges();
            return seriesByShowName;
        }
    }

And the relevant model:

public class Episode
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]
    public virtual int EpisodeId { get; set; }
    public virtual Series Series { get; set; }

    // ...

}

public class Series
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]
    public int SeriesId { get; set; }
    public string SeriesName { get; set; }
    public ObservableCollection<Episode> Episodes { get; set; }

    public Series()
    {
    }

    // ...
}

Are you sharing the same DBContext Instance in test and Factory? If not this is the problem that you are using difererent DBContext Instances in your factory method and in your test.

If you use different DBContext instances Entity Framework is not able to kwnow that series object exist in database, series become a deattached object for the DBContest instance in your test (google for deattached entity framework)

You have to share the same DBContext instance across test and factory, or work with series as deatthaced object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM