0

次の構造のレガシーデータベーステーブルがあります

CREATE TABLE [dbo].[MASTER_PROJECT](
    [DATA_ID] [bigint] IDENTITY(1,1) NOT NULL,
    ......
    [GENRE_DATA_ID] [bigint] NULL,  
    [ADDITIONAL_GENRE_DATA_ID] [bigint] NULL,
    [ADDITIONAL_GENRE_2_DATA_ID] [bigint] NULL )

EF 5を使用して次のクラスをマッピングしたい(コードファースト)

public class Project {
   public long Id {get;set;}
   public ICollection<Genre> Genres {get;set;}
}

public class Genre {
   public long Id {get;set;}
   // other stuff
}

最初は、ジャンルを配列にして、このようにマッピングしてみました

    HasOptional(t => t.Genres[0]).WithOptionalDependent().Map(m => m.MapKey("GENRE_DATA_ID"));
    HasOptional(t => t.Genres[1]).WithOptionalDependent().Map(m => m.MapKey("ADDITIONAL_GENRE_DATA_ID"));
    HasOptional(t => t.Genres[2]).WithOptionalDependent().Map(m => m.MapKey("ADDITIONAL_GENRE_2_DATA_ID"));

ただし、これによりエラーが発生し、t.Genres[0]は有効なプロパティではありません。(これは理にかなっています)

これをどのように行うかについてのアイデアはありますか?ありがとう!

4

2 に答える 2

0

やりたいことはEFとは何の関係もありません。アイテムのコレクションを返す新しいメソッドまたはプロパティを使用して、このエンティティの部分的なクラスを実装する必要があります。もちろん、このコレクションにさまざまなジャンルのデータIDプロパティの値を入力する必要があります。例えば:

public ICollection<Genre?> GenreDataIDs
{
    get 
    {
        var col = new List<Genre?>() { GENRE_DATA_ID_NavProperty, ADDITIONAL_GENRE_DATA_ID_NavProperty, ..., ADDITION_GENRE_N_DATA_ID_NavProperty };

        return col;
    }
}

ナビゲーションプロパティには、Genre1、Genre2などの名前が付けられている可能性があります。説明のために、列名に_NavPropertyを追加しただけです。

コレクションを使用して基になるDBレコードを更新する場合は、より複雑になります(最も簡単な実装は、SetGenreDataID(int index、int?value)メソッドを実装することです)

于 2013-03-26T21:02:31.950 に答える
0

モホの助けを借りて、これが私が最終的に私が望むものを手に入れた方法です。

また、このドメインエンティティを収容するプロジェクトが、マッピングプロジェクトに表示される内部を許可することを確認する必要があります。(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);
        }
    }
}
于 2013-04-02T21:49:28.997 に答える