【发布时间】:2015-07-30 16:27:06
【问题描述】:
我不确定协议是什么 w.r.t。改变你的问题,但我想如果我改变它会更好,因为有很多信息并且提出问题的初衷已经丢失。
原问题:
我最初在使用 EF(代码优先方法/POCO 类)生成数据库时遇到问题。 问题之一是我在实体类中使用构造函数来初始化成员。在@RickStahl 建议不需要之后,我改变了我的实现。
为了读者,我不希望信息丢失,因为一些老的 cmets 打算解决这个问题。
但是,自从最初创建此线程以来,情况发生了变化。我已经能够克服一些问题。
当前问题:
我在从基础数据库表中检索内容时遇到问题。
例外: 对象引用未设置为对象的实例。
异常发生在 Program.cs 的以下语句(第 21 行):
foreach(PhoneNumber p in cd.Phones)
为了便于理解问题,我粘贴了整个源代码。
这是我的 Entity 类的源代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ConsoleApplication1
{
public class ContactData
{
[Key]
public int ContactId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IList<PhoneNumber> Phones { get; set; }
public IList<EmailAddress> Emails { get; set; }
}
public class PhoneNumber
{
[Key]
public int PhoneId { get; set; }
public int ContactId { get; set; }
public string Phone { get; set; }
public ContactData ContactData { get; set; }
public PhoneNumber()
{
}
}
public class EmailAddress
{
[Key]
public int EmailId { get; set; }
public int ContactId { get; set; }
public string Email { get; set; }
public ContactData ContactData { get; set; }
public EmailAddress()
{
}
}
}
ContactContext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace ConsoleApplication1
{
public class ContactContext : DbContext
{
public ContactContext()
: base("ContactDBContext")
{
Database.SetInitializer<ContactContext>(new DropCreateDatabaseIfModelChanges<ContactContext>());
}
public DbSet<ContactData> Contacts { get; set; }
}
}
ContactManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class ContactManager
{
ContactContext cDbContext = new ContactContext();
public IList<ContactData> GetContactList()
{
IQueryable<ContactData> cContactList = cDbContext.Contacts;
IList<ContactData> cListData = new List<ContactData>();
cListData = cContactList.ToList();
return cListData;
}
}
}
Program.cs(入口点)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
ContactManager cMgr = new ContactManager();
foreach (ContactData cd in cMgr.GetContactList())
{
Console.WriteLine(cd.ContactId);
Console.WriteLine(cd.FirstName);
Console.WriteLine(cd.LastName);
foreach(PhoneNumber p in cd.Phones)
{
Console.WriteLine(p.Phone);
}
foreach (EmailAddress e in cd.Emails)
{
Console.WriteLine(e.Email);
}
}
Console.ReadKey();
}
【问题讨论】:
-
好吧,正如消息所说,您在 ContactData 上没有无参数构造函数,您在创建集合时调用它。如果您想简化设置,您可能需要查看 automapper。
-
@SteveGreene 当您为实体对象提供参数化构造函数时,使用 O/RM 是否过于复杂?
-
要使 EF 工作,您的实体需要有一个无参数构造函数。无论如何,当您可以使用更加灵活的参数分配语法时,所有这些参数都是多余的。
-
你可以做到,但你想达到什么目的?您上面的代码不需要它们。我喜欢我的 POCO 最小化,然后我在控制器中构建一个视图模型并使用 AutoMapper 来回传输数据。有点学习曲线,但效果很好。 lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models
-
试试 IQueryable
cContactList = cDB.Contacts.Include(c => c.Phones).Include(c => c.Emails);
标签: asp.net-mvc-4 c#-4.0 ef-code-first entity-framework-6 poco