c# - Merge complex entity graph with database -
in code first data model i'm retrieving info id3 tags , putting database. have following table relations:
master entity track. fields: artists, composers, performers many many relationship , conductor many one. of type artist.
ids of entities generated hashing various properties on creation of object:
- in track it's path,
- in album it's name combined names of contained artists , index field (it's because there may duplicate album names define album uniquely need include artists; index field represents possible multiple discs per album),
- in picture it's data,
- the remaining entities ids field name.
code creating track (with 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 entityhashset<artist>).exceptwith(duplicatecomposers); (composers 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 entityhashset<artist>).exceptwith(duplicateperformers); (performers 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 = 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) }; } } }
code creating album:
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 extension method combine 2 hashcodes } }
ids set so:
[required] public string name { { return name; } set { name = value; id = name.tolowerinvariant().gethashcode(); } }
when insert single track whole graph database good. have check possible duplicates in artists, composers, performers , conductor. can replace references duplicates added objects same ids.
when have insert multiple tracks however, problems start arise. don't know how approach possible collisions.
for example. i'm adding 2 tracks album name "a". track 1 have genres "rock; blues", track 2 "blues; metal". album "a" must genres "rock; blues; metal". also, if album have different trackcount last 1 added determine value.
to achieve desired results have query database crazy in creation of single track object or there more elegant solution? tips me on right path appreciated.
Comments
Post a Comment