2016-05-22 4 views
1

Songには、それ自体が多対多の関係を持っています。両方のID列を持つSimilarVersionというクラスにこれらのIDを格納します。ASP.NET MVC Entity Frameworkで生成された外部キーにアクセスする方法は?

public class Song 
{ 
    public int Id { get; set; } 

    public string AudioName { get; set; } 

    public string ArtistName { get; set; } 

    ... 

    public virtual ICollection<SimilarVersion> SimilarVersions { get; set; } = new List<SimilarVersion>();  
} 

public class SimilarVersion 
{ 
    public int Id { get; set; } 

    public int? Song_Id1 { get; set; } 
} 

ビューモデル:EFはSong_Idを生成しているように私のデータベース内

public class SongDto 
{ 
    public int Id { get; set; } 

    public string AudioName { get; set; } 

    public string ArtistName { get; set; } 

    ... 

    public ICollection<SimilarSongDto> SimilarSongDtos { get; set; } = new List<SimilarSongDto>(); 
} 

public class SimilarSongDto 
{ 
    public int Id { get; set; } 

    public string AudioName { get; set; } 

    public string ArtistName { get; set; } 

    ... 
} 

SimilarVersionテーブルは今、IdSong_IdSong_Id1を持っています。私のコードでそのEF生成列を使用する方法を教えてください。

_similarVersionService.GetSimiliarVersion().Song_Idというクラス内にプロパティがないため、エラーが発生します。 Song_Id1と同じように手動でクラスに追加して他のクラスのコレクションを削除することもできますが、何か間違っていると思います。また、これをマッピングするより良い方法があるかどうか教えてください。

public int Song_Id { get; set; }を追加しようとしましたが、私のテーブルにSong_Id2という別の列が作成されました。

public ActionResult Song(int id) 
{ 
    //Map the domainModel to songViewModel 
    var songDto = Mapper.Map<Song, SongDto>(_songService.GetSong(id)); 

    //Get all of the songs where the id == the Song_Id column in similar version table 
    var songs = _songService.GetSongs().ToList() 
       .Where(x => x.SimilarVersions.Any(z => z.Song_Id == songDto.Id)) 
       .ToList(); //z.Song_Id no definition found 

    //Map the Song domain to SimilarSong ViewModel and assign it to the songDto to be passed to the view 
    songDto.SimilarSongDtos = Mapper.Map<ICollection<Song>, ICollection<SimilarSongDto>>(songs); 

    return View(songDto); 
} 

編集。 Admir回答に基づいて行を追加しようとする:

var songToUpload = new Song 
{ 
    AudioName = uploadSongDtos[i].AudioName.Trim(), 
    ArtistName = uploadSongDtos[i].ArtistName,       
}; 

foreach (var compareAgainstString in _songService.GetSongs().ToDictionary(x => x.Id, x => x.AudioName)) 
{ 
     var score = SearchContext.Levenshtein.iLD(songToUpload.AudioName, compareAgainstString.Value); 

     //Don't add the current song 
     if (score < 50 && songToUpload.Id != compareAgainstString.Key) 
      songToUpload.SimilarVersionsWhereSimilar.Add(new SimilarVersion { SimilarId = compareAgainstString.Key }); 
} 

両方OriginalIdSimilarIdsongToUpload.IdのIDがOriginalIdため正しい我々はモデルで定義された関係を、与えられたどのように割り当てられているが、それはまた、オーバーライドされ私のカスタムセットはSimilarIdです。どうすればこれをやめることができますか?

答えて

0

あなたは、このアプローチを取ることができます:

public class Song 
{ 
    public int Id { get; set; } 

    public string ArtistName { get; set; } 

    public virtual IList<Similarity> SimilaritiesWhereOriginal { get; set; } 

    public virtual IList<Similarity> SimilaritiesWhereSimilar { get; set; } 
} 

public class Similarity 
{ 
    public int Id { get; set; } 

    public int OriginalId { get; set; } 
    public virtual Song Original { get; set; } 

    public int SimilarId { get; set; } 
    public virtual Song Similar { get; set; } 
} 

public class ApplicationDbContext : DbContext 
{ 
    public DbSet<Song> Songs { get; set; } 

    public DbSet<Similarity> Similarities { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Song>().HasMany(x => x.SimilaritiesWhereOriginal).WithRequired(x => x.Original).WillCascadeOnDelete(false); 
     modelBuilder.Entity<Song>().HasMany(x => x.SimilaritiesWhereSimilar).WithRequired(x => x.Similar).WillCascadeOnDelete(false); 
     base.OnModelCreating(modelBuilder); 
    } 
} 

類似のクラスを「オリジナル」の歌と「類似」の歌との関係を示したものです。このクラスは、EF自動生成テーブルを、コードからアクセスできる多対多リレーションシップテーブルに置き換えます。

+0

答えをありがとう。あなたの答えを使って 'SimilarVersion'テーブルに行を追加しようとしましたが、期待通りに動作しません。私は問題を示すために私の元の質問を編集しました。私はまた、 '類似性'表に 'public virtual song Original'と' public virtual song similar'がなぜ必要なのか理解していません。おそらく私はそれを正しく実装していないと思う。 –

0

IDは実際にあなたの店によって生成される可能性があります。それを作成するにはContext.SaveChanges()に電話し、、次にを読んでください。

+0

クラスにプロパティがない場合、IDを読み取るにはどうすればよいですか?これはコンパイル時のエラーです。 –

+0

私の電話では、質問の一部を読むのが難しくなりました。 EF6では、結合表のプロパティにアクセスすることが難しくなります。通常、IDを取得する前にオブジェクトを取得します。 – shannon

関連する問題