3

Asp.Net MVCプロジェクトを起動して実行しており、モデルが変更されたときに、タイプの1つのプロパティを除いて、データベースに必要なすべてのデータをシードできますList<string>

問題をよりよく示すために、そのテストケースを分離しました。

私が単純なPersonモデルを持っているとしましょう:

class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public List<string> Children { get; set; }

    public string ToString()
    {
        string children = "";

        if (Children != null)
        {
            children = String.Join(" - ", Children.ToArray());
        }
        else
        {
            children = "none";
        }

        return Firstname + " " + Lastname + " -> " + children;
    }
}

このモデルを外部コンソールアプリケーションで使用すると、そのすべてのメンバーを初期化できます。

class Program
{
    static void Main(string[] args)
    {
        List<Person> myList = new List<Person> {
            new Person { Firstname = "John", Lastname = "Doe", Children = new List<string> { "Bob", "Monica" }},
            new Person { Firstname = "Bob", Lastname = "Doe", Children = new List<string> { "Jack", "John II" }},
            new Person { Firstname = "Monica", Lastname = "Doe", Children = new List<string> { "Sue", "Mark" }}
        };

        // output the list to screen
        myList.ForEach(p => Console.WriteLine(p.ToString()));
    }
}

その場合、出力は期待どおりになります。

John Doe -> Bob - Monica
Bob Doe -> Jack - John II
Monica Doe -> Sue - Mark

しかし、同じデータをデータベースにシードしようとすると、Childrenメンバーはnull

これが私がそれをやろうとしている方法です:

public class MySeedData : DropCreateDatabaseIfModelChanges<MyDataBaseContextClass>
{
    protected override void Seed(MyDataBaseContextClass context)
    {
        List<Person> myList = new List<Person> {
            new Person { Firstname = "John", Lastname = "Doe", Children = new List<string> { "Bob", "Monica" }},
            new Person { Firstname = "Bob", Lastname = "Doe", Children = new List<string> { "Jack", "John II" }},
            new Person { Firstname = "Monica", Lastname = "Doe", Children = new List<string> { "Sue", "Mark" }}
        };
        myList.ForEach(p => context.Persons.Add(p));
    }
}

私はさまざまな構築パターンを試しましたが、Childrenメンバーがnull自分のビューの1つでそれにアクセスしようとするたびに。

現時点では、このメンバーがnullでないことがわかった唯一の方法は、Personクラスのデフォルトコンストラクターでリストを初期化することです...

Childrenでは、このメンバーに、個人ごとに異なる値を使用してデータをシードするにはどうすればよいですか?

4

2 に答える 2

1

次のように、クラスのコンストラクターでこれを行う必要があります。

class Person {
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public List<string> Children { get; set; }
    public Person() {
        Children = new List<string>();
    }
    public Person(string first, string last, IEnumerable<string> children) {
        FirstName = first;
        LastName = last;
        Children = children.ToList();
    }
    ...
}

どのように構築してもPerson、そのChildrenメンバーはになりませんnull。構文の代わりにコンストラクターの2番目のオーバーロードを呼び出す必要がありnew Person{...}ます。これにより、セッターをプライベートにすることができます(通常、これは良いことです)。

于 2012-10-19T10:44:43.263 に答える
1

問題は、EFがスカラーのコレクションをサポートしていないことです。つまり、Code Firstは、Listの処理方法を知らないため、Childrenプロパティをマッピングしていません。

これを回避する1つの方法は、リスト内のアイテムのエンティティタイプを定義し、代わりにそれを使用することです。例えば:

public class Person
{
    public int Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public virtual List<Child> Children { get; set; }
    // Your other code
}

public class Child
{
    public int Id { get; set; }
    public string Name { get; set; }
}

チャイルドクラスの形は、それがどのように使用されているかによって少し異なる可能性がありますが、質問からは明らかではありません。また、EFでは各エンティティタイプにキーが必要なため、キーとして機能するプロパティを追加しました。繰り返しますが、これを変更することをお勧めします。最後に、プロパティを仮想化して、必要なときに遅延ロードされるようにしました。

于 2012-10-19T23:04:59.120 に答える