将复杂实体图与数据库

时间:2015-06-15 02:57:08

标签: c# entity-framework

在我的代码第一个数据模型中,我正在从ID3标签中检索信息并将其放入数据库。我有以下表关系:

model

主要实体是Track。它的领域:艺术家,作曲家,表演者是多对多的关系和指挥多对一。所有类型艺术家。

所有实体的ID都是在创建对象时散列各种属性生成的:

  • 跟踪它的路径,
  • 在相册中,它的名称与所包含的艺术家和索引字段的名称相结合(因为可能存在重复的相册名称,因此要唯一地定义相册我需要包括艺术家;索引字段表示每张专辑可能有多个光盘),
  • In Picture it's Data,
  • 其余实体ID来自字段名称。

创建跟踪的代码(在taglib-sharp的帮助下):

public Track(string path)
    {
        Path = path;

        using (var f = new AudioFile(path))
        {
            BeatsPerMinute = f.Tag.BeatsPerMinute != 0 ? (int?)f.Tag.BeatsPerMinute : null;
            Index = f.Tag.Track != 0 ? (int?)f.Tag.Track : null;
            Year = f.Tag.Year != 0 ? (int?)f.Tag.Year : null; 

            Comment = f.Tag.Comment;
            Copyright = f.Tag.Copyright;
            Lyrics = f.Tag.Lyrics;
            Title = f.Tag.Title;               



            var artists = f.Tag.Artists.Any() ? f.Tag.Artists : f.Tag.AlbumArtists;
            Artists = new EntityHashSet<Artist>(artists.Select(a => new Artist(a.Trim())));

            Composers = new EntityHashSet<Artist>(f.Tag.Composers.Select(c => new Artist(c.Trim())));

            Performers = new EntityHashSet<Artist>(f.Tag.Performers.Select(p => new Artist(p.Trim())));

            var duplicateComposers = Composers.Where(c => Artists.Any(a => a.Id == c.Id)).ToList();
            (Composers as EntityHashSet<Artist>).ExceptWith(duplicateComposers);
            (Composers as EntityHashSet<Artist>).UnionWith(Artists.Where(a => duplicateComposers.Any(c => c.Id == a.Id)));

            var artistsComposers = Artists.Union(Composers).ToList();
            var duplicatePerformers = Performers.Where(p => artistsComposers.Any(a => a.Id == p.Id)).ToList();
            (Performers as EntityHashSet<Artist>).ExceptWith(duplicatePerformers);
            (Performers as EntityHashSet<Artist>).UnionWith(artistsComposers.Where(a => duplicatePerformers.Any(c => c.Id == a.Id)));

            var artistsComposersPerformers = artistsComposers.Union(Performers).ToList();
            if (!String.IsNullOrWhiteSpace(f.Tag.Conductor))
            {
                Conductor = new Artist(f.Tag.Conductor.Trim());
                var a = artistsComposersPerformers.FirstOrDefault(c => c.Id == Conductor.Id);
                if (a != null)
                {
                    Conductor = a;
                }
            }

            Pictures = new EntityHashSet<Picture>(f.Tag.Pictures.Select(p => new Picture(p)));

            Genres = new EntityHashSet<Genre>(f.Tag.Genres.Select(g => new Genre(g.Trim())));

            if (!String.IsNullOrWhiteSpace(f.Tag.Album))
            {
                Album = new Album(f.Tag.Album.Trim(), Artists)
                {
                    TrackCount = f.Tag.TrackCount != 0 ? (int?)f.Tag.TrackCount : null,
                    AlbumCount = f.Tag.DiscCount != 0 ? (int?)f.Tag.DiscCount : null,
                    Index = f.Tag.Disc != 0 ? (int?)f.Tag.Disc : null,

                    FrontCover = Pictures.SingleOrDefault(p => p.Type == PictureType.FrontCover),
                    BackCover = Pictures.SingleOrDefault(p => p.Type == PictureType.BackCover) 
                };
            }


        }
    }

创建相册的代码:

public Album(string name)
        : this()
    {
        Name = name;
    }

public Album(string name, IEnumerable<Artist> artists)
        : this(name)
    {
        var sortedArtists = artists.ToList();
        sortedArtists.Sort();
        Artists = new EntityHashSet<Artist>(sortedArtists);

        Id = Id.WithHash(Index.Value);

        foreach (var artist in sortedArtists)
        {
            Id = Id.WithHash(artist.Id); // WithHash is extension method to combine two hashcodes
        }
    }

Ids设置如下:

[Required]
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            Id = name.ToLowerInvariant().GetHashCode();
        }
    }

当我将包含整个图表的单个Track插入数据库时​​,一切都很好。我必须检查艺术家,作曲家,表演者和指挥中可能存在的副本。然后我可以将重复项的引用替换为具有相同ID的先前添加的对象。

但是当我必须插入多个曲目时,问题就开始出现了。我不知道如何处理可能的碰撞。

例如。我正在添加两个专辑名称为“A”的曲目。曲目1有流派“摇滚;蓝调”,曲目2“蓝调;金属”。专辑“A”必须与流派“摇滚;布鲁斯;金属”。此外,如果此专辑具有不同的TrackCount,则添加的最后一个将确定此值。

为了达到预期的效果,我必须像创建单个Track对象那样疯狂地查询数据库,还是有更优雅的解决方案?任何能让我走上正确道路的提示都会受到赞赏。

0 个答案:

没有答案