モホの助けを借りて、これが私が最終的に私が望むものを手に入れた方法です。
また、このドメインエンティティを収容するプロジェクトが、マッピングプロジェクトに表示される内部を許可することを確認する必要があります。(AssemblyInfo.cs内)
[assembly: InternalsVisibleTo("YOUR.MAPPING.PROJECT")]
エンティティ定義
public class Project
{
private ObservableCollection<Genre> _genres;
protected internal virtual Genre Genre1 { get; set; }
protected internal virtual Genre Genre2 { get; set; }
protected internal virtual Genre Genre3 { get; set; }
public IList<Genre> Genres
{
get
{
if (_genres == null)
{
_genres = new ObservableCollection<Genre>(new[] {Genre1, Genre2, Genre3});
_genres.CollectionChanged += GenresCollectionChangedHandler;
}
return _genres;
}
}
private void SetGenreByIndex(int index, Genre g)
{
switch (index)
{
case 0: Genre1 = g; break;
case 1: Genre2 = g; break;
case 2: Genre3 = g; break;
}
}
private void GenresCollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
{
_genres.CollectionChanged -= GenresCollectionChangedHandler;
int max = 3;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
if (_genres.Count > max)
{
_genres.RemoveAt(max);
_genres.CollectionChanged += GenresCollectionChangedHandler;
throw new IndexOutOfRangeException("Not allowed to store more than 3 genres.");
}
SetGenreByIndex(_genres.Count - 1, e.NewItems[0] as Genre);
break;
case NotifyCollectionChangedAction.Replace:
for (var i = 0; i < e.NewItems.Count; i++)
SetGenreByIndex(i + e.NewStartingIndex, e.NewItems[i] as Genre);
break;
case NotifyCollectionChangedAction.Reset:
Genre1 = null;
Genre2 = null;
Genre3 = null;
_genres.Clear();
break;
}
_genres.CollectionChanged += GenresCollectionChangedHandler;
}
}
これがCodeFirstMappingクラスです
public class ProjectConfiguration
{
public ProjectConfiguration()
{
// ...
// GENRES collection
Ignore(t => t.Genres);
HasOptional(t => t.Genre1).WithMany().Map(m => m.MapKey("GENRE_DATA_ID"));
HasOptional(t => t.Genre2).WithMany().Map(m => m.MapKey("GENRE_DATA_ID_1"));
HasOptional(t => t.Genre3).WithMany().Map(m => m.MapKey("GENRE_DATA_ID_2"));
}
}
そしてここにそれが機能することを確認するためのテスト方法があります
[TestClass]
public class ProjectUnitTests
{
[TestMethod]
public void SwapGenresInListAndSaveTest()
{
//Arrange
Genre original1 = null;
Genre original2 = null;
using (var context = new MyContext())
{
context.Configuration.LazyLoadingEnabled = true;
//ACT
var project = context.Projects.Find(2341);
original1 = project.Genres[0];
original2 = project.Genres[1];
genres[0] = original2;
genres[1] = original1;
//Save to DB
context.SaveChanges();
}
//ASSERT
using (var context = new MyContext())
{
var project1 = context.Projects.Find(2341);
//ASSERT
Assert.IsNotNull(project1);
Assert.IsNotNull(project1.Genres);
Assert.AreEqual(3, project1.Genres.Count);
Assert.AreEqual(original2.DataId, project1.Genres[0].DataId);
Assert.AreEqual(original1.DataId, project1.Genres[1].DataId);
}
}
}