在我的代码第一个数据模型中,我正在从ID3标签中检索信息并将其放入数据库。我有以下表关系:
主要实体是Track。它的领域:艺术家,作曲家,表演者是多对多的关系和指挥多对一。所有类型艺术家。
所有实体的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对象那样疯狂地查询数据库,还是有更优雅的解决方案?任何能让我走上正确道路的提示都会受到赞赏。