如何仅使用导航属性集创建+ persist + has-a-proxy到代码优先poco的新实例?在下面的代码中,我将展示如何使用成员函数创建随后创建POCO的POCO。您没有DbContext,但是如果您创建一个对象并使用DbSet.Add持久化,则返回的对象不是代理,因此您不能再使用其DbSet.Add添加不同的子对象
在此代码中,如果您调用MailingList.AddIncomingMessage(“我的消息”),则会在“OOPS”注释中获得异常,因为创建的msg不是代理,因此其Message.doodads属性为null。
class Doodad {
public int ID { get; set; }
public string doodad { get; set; };
}
class Message {
public int ID { get; set; }
public virtual MailingList mailingList { get; set; }
public virtual ICollection<Doodad> doodads { get; set; }
public string text { get; set; }
public void GetDoodadCreateIfNeeded(string doodad) {
try {
// won't be found since we just created this Message
return this.doodads.First(d => d.doodad == doodad);
} catch (Exception e) {
Doodad newDoodad = new Doodad() { doodad=doodad };
// OOPS! this.doodads == null, because its not a proxy object
this.doodads.Add(newDoodad);
return newDoodad;
}
}
}
class MailingList {
public int ID { get; set; }
public virtual ICollection<Message> messages { get; set; }
public void AddIncomingMessage(string message) {
var msg = new Message() { text=message };
// we have no Context, because we're in a POCO's member function
this.messages.Add(msg);
var doodad = msg.GetDoodadCreateIfNeeded("bongo drums");
}
}
编辑:抱歉,伙计们,我忘了将属性访问者和ID放入这个简化的案例中,但我在实际代码中使用它们。
答案 0 :(得分:2)
它与代理无关。它与任何其他代码相同 - 如果您想使用对象/集合,您必须首先初始化它!你的第一个命令:
return this.doodads.First(d => d.doodad == doodad);
不会抛出异常,因为它没有找到doodad
,而是因为doodads
为空。
你需要做什么?您需要在首次使用它们之前初始化集合。你可以这样做:
答案 1 :(得分:1)
导航属性的补充,您需要具有属于外键ID的属性。
因此,您的MailingList需要具有此属性:
[Key] // this attribute is important
public int Id { get; set; }
并且您必须更改Message classe以具有以下属性:
public virtual int mailingListId { get; set;
public virtual MailingList mailingList { get; set; }
{ get; set; }
属性很重要,因此它是属性,而不仅仅是公共属性。