3

我有一个 Asp.Net MVC 项目启动并运行,当我的模型发生更改时,我可以将我想要的所有数据播种到数据库中,除了一个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

目前,我发现让这个成员不为空的唯一方法是在Person类的默认构造函数中初始化列表......

那么如何Children为每个人提供不同值的数据给这个成员呢?

4

2 回答 2

1

问题是 EF 不支持标量集合。换句话说,Code First 没有映射您的 Children 属性,因为它不知道如何处理 List。

解决此问题的一种方法是为列表中的项目定义实体类型并改用它。例如:

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

您的 Child 类的形状可能会有所不同,具体取决于它的确切使用方式,这在问题中并不清楚。我还添加了属性作为键,因为 EF 要求每个实体类型都有一个键;您可能想再次更改此设置。最后,我将属性设为虚拟,以便在需要时延迟加载。

于 2012-10-19T23:04:59.120 回答
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。您应该调用构造函数的第二个重载来代替new Person{...}语法,这样您就可以将 setter 设为私有(通常,这是一件好事)。

于 2012-10-19T10:44:43.263 回答