代码优先,处理关系,播种

时间:2013-03-12 22:34:30

标签: asp.net entity-framework reference code-first

我想简单地在已存在的两个实体之间创建一个关系..

在我的情况下,我有一个专辑实体,可能有多个类型(也是一堆实体)

我的相册模型如下所示:

public class AlbumModel : IModel
{
    public List<GenreModel> Genres { get; set; }
    public ArtistModel Artist { get; set; }
    public Guid Id { get; set; }
    public string Title { get; set; }
    public float Price { get; set; }
    public string ArtUrl { get; set; }
}

然后我想在Album模型对象和一堆GenreModel对象/实体之间创建一个关系..

在&#34;正常&#34;实体框架我只是分配一个新的EntityKey ..但我不太确定如何使用代码首先执行此操作.. 我还注意到有些人为他们想要在...之间创建引用的实体有一个名为xxxxId的额外属性,然后简单地为xxxxId属性赋值,这有些神奇地创建了实体之间的引用..我猜这个适用于一对一或一对多的关系。但我想这对多对多关系不起作用..或者?

无论如何..这是我的GenresModel:

public class GenreModel : IModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public List<AlbumModel> Albums { get; set; }
}

这就是我之前尝试过的...但是这不会创建关系......只会在我的数据库中创建一个额外的实体/行..

var artistRepository = new ArtistRepository();
        var genresRepository = new GenreRepository();

        #region Lordi
        context.Albums.Add
            (
                new AlbumModel
                {
                    Artist = artistRepository.GetByName("Lordi"),
                    ArtUrl = "http://upload.wikimedia.org/wikipedia/en/8/8f/The_Monster_Show.jpg",
                    Genres = new List<GenreModel> { genresRepository.GetByName("Rock"), genresRepository.GetByName("Hard rock") },
                    Id = Guid.NewGuid(),
                    Price = 3,
                    Title = "The Monster Show",
                }
            );
        context.Albums.Add
            (
                new AlbumModel
                {
                    Artist = artistRepository.GetByName("Lordi"),
                    ArtUrl = "http://www.nuclearblast.de/static/articles/157/157892.jpg/1000x1000.jpg",
                    Genres = new List<GenreModel> { genresRepository.GetByName("Rock"), genresRepository.GetByName("Hard rock") },
                    Id = Guid.NewGuid(),
                    Price = 10,
                    Title = "Zombilation - The Greatest Cuts",
                }
            );
        #endregion

...并且为了记录......不,我不听Lordi :) ..只是虚拟数据..而且对于一些奇怪的原因,Lordi是第一个想到的乐队..

提前致谢!

2 个答案:

答案 0 :(得分:2)

所以基本上你正试图在EF中建立多对多的关系。我假设有一个表格可以链接数据库中的专辑和流派?如果是这样,你需要让EF知道关系和它所存储的表格,正如我已经解释过here。您可以通过Google搜索“在实体框架中设置多对多”等内容来查找大量额外信息。

另外,您可能还想将集合属性更改为虚拟,而不是

public List<GenreModel> Genres { get; set; }

你会有

public virtual ICollection<GenreModel> Genres { get; set; }

这允许EF在这些属性上执行延迟加载,从而加快了它的速度。

答案 1 :(得分:1)

如您所述指定这些集合属性将自动创建名为GenreModelAlbumModels的多对多链接表。

但是,我怀疑您的存储库阻止EF知道存在关系。如果您没有在同一数据上下文中加载GenreModel实体,则可能不知道它们之间存在链接。例如,此代码有效:

    using (var context = new DataContext())
    {
        #region Lordi

        context.Albums.Add
            (
                new AlbumModel
                {
                    ArtUrl = "http://upload.wikimedia.org/wikipedia/en/8/8f/The_Monster_Show.jpg",
                    Genres = new List<GenreModel> { context.Genres.First(i => i.Name == "Rock"), context.Genres.First(i => i.Name == "Hard Rock") },
                    Id = Guid.NewGuid(),
                    Price = 3,
                    Title = "The Monster Show",
                }
            );

        context.SaveChanges();

        #endregion
    }

GenreModels连接到我们添加AlbumModels的相同上下文,因此EF知道实体之间存在关系。

要确保它正常工作,请在数据库中查找该链接表。它将在代码中隐藏起来。