我启动并运行了一个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
成员提供数据?
答案 0 :(得分: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设为私有(通常,这是一件好事)。
答案 1 :(得分: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要求每个实体类型都有一个密钥;再次你可能想改变这个。最后,我将属性设置为虚拟,以便在需要时可以延迟加载。