2016-05-22 78 views
1

Song與自己有多對多的關係。我將這些ID存儲在名爲SimilarVersion的類中,並帶有兩個ID列。ASP.NET MVC如何訪問實體框架生成的外鍵?

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; } 
} 

視圖模型:

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已經產生Song_Id。我如何在代碼中使用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 }); 
} 

兩個OriginalIdSimilarId被分配到任何的songToUpload.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); 
    } 
} 

相似性類別顯​​示爲「原創」歌曲和「類似的」歌之間的關係。此類使用您可以從代碼訪問的您自己的many-2-many關係表替換EF自動生成的表。

+0

感謝您的回答。我一直在嘗試使用你的答案將一行添加到「SimilarVersion」表中,但它沒有按預期工作。我編輯了我的原始問題以顯示問題。我也不明白爲什麼我們需要'Similarity'表中的'public virtual Song Original'和'public virtual Song Similar'。我想也許我正在實施它不正確。 –

0

該ID實際上可能是由您的商店生成的。請致電Context.SaveChanges()創建它,然後讀取ID。

+0

如果課堂上沒有任何屬性,我該如何閱讀ID?這是編譯時錯誤。 –

+0

我的手機很難閱讀您的部分問題。 EF6很難訪問連接表屬性。通常,您在獲取ID之前先獲取對象。 – shannon