以下是我正在尝试做的示例代码,我正在获取NullReferenceException
。如果我删除OneToManyCascadeDeleteConvention
,那么一切正常。谁能帮助我理解这里的问题。
public class MessageBoard
{
public int Id { get; set; }
}
public class Post
{
public Post()
{
this.Messages = new HashSet<Message>();
this.PostHistories = new HashSet<PostHistory>();
}
public int Id { get; set; }
[Required]
public int MessageBoardId { get; set; }
public virtual MessageBoard MessageBoard { get; set; }
public virtual ICollection<Message> Messages { get; set; }
public virtual ICollection<PostHistory> PostHistories { get; set; }
}
public class Message
{
public int Id { get; set; }
[Required]
public int PostId { get; set; }
public virtual Post Post { get; set; }
public virtual ICollection<MessageHistory> MessageHistories { get; set; }
}
public class MessageBoardVersion
{
public int Id { get; set; }
[Required]
public int MessageBoardId { get; set; }
public virtual MessageBoard MessageBoard { get; set; }
public virtual ICollection<PostHistory> PostHistories { get; set; }
}
public class PostHistory
{
public PostHistory()
{
this.MessageHistories = new HashSet<MessageHistory>();
}
[Key, Column(Order = 0)]
[ForeignKey("MessageBoardVersion")]
public int MessageBoardVersionId { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Post")]
public int PostId { get; set; }
public virtual MessageBoardVersion MessageBoardVersion { get; set; }
public virtual ICollection<MessageHistory> MessageHistories { get; set; }
public virtual Post Post { get; set; }
}
public class MessageHistory
{
[Key, Column(Order = 2)]
[ForeignKey("Message")]
public int MessageId { get; set; }
[Key, Column(Order = 0)]
[ForeignKey("PostHistory")]
public int MessageBoardVersionId { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("PostHistory")]
public int PostId { get; set; }
public virtual PostHistory PostHistory { get; set; }
public virtual Message Message { get; set; }
}
public class MessageHistoryConfiguration : EntityTypeConfiguration<MessageHistory>
{
public MessageHistoryConfiguration()
{
this.HasRequired(p => p.Message).WithMany(p => p.MessageHistories).WillCascadeOnDelete(false);
this.HasRequired(p => p.PostHistory).WithMany(p => p.MessageHistories).WillCascadeOnDelete(true);
}
}
public class PostHistoryConfiguration : EntityTypeConfiguration<PostHistory>
{
public PostHistoryConfiguration()
{
this.HasRequired(p => p.MessageBoardVersion).WithMany(p => p.PostHistories).WillCascadeOnDelete(false);
}
}
public class Model1Container : DbContext
{
public Model1Container()
: base("name=Model1Container")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
/*
*
* If I do Remove<OneToManyCascadeDeleteConvention> then code works fine
*/
//modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
//modelBuilder.Configurations.Add(new PostHistoryConfiguration());
modelBuilder.Configurations.Add(new MessageHistoryConfiguration());
}
public DbSet<MessageBoard> MessageBoards { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<MessageBoardVersion> MessageBoardVersions { get; set; }
public DbSet<PostHistory> PostHistories { get; set; }
public DbSet<MessageHistory> AnswerHistories { get; set; }
}
存在多个级联路径错误,因此如果我尝试在删除时禁用级联,则会出现以下异常
System.NullReferenceException未处理
的HResult = -2147467261
Message =对象引用未设置为对象的实例 来源=的EntityFramework
堆栈跟踪:
在System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EdmEntityType entityType,EdmModel model)
在System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntities(EdmModel模型)
在System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(EdmModel模型)
在System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest,DbProviderInfo providerInfo)
在System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
在System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
在System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput输入)
在System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
在System.Data.Entity.Internal.InternalContext.CreateObjectContextForDdlOps()
在System.Data.Entity.Database.Create(Boolean skipExistsCheck)
在System.Data.Entity.Database.Create()
在ConsoleApplication2.Program.Main(String [] args)中的c:\ Users \ dhawalh \ Documents \ Visual Studio 2012 \ Projects \ ConsoleApplication2 \ ConsoleApplication2 \ Program.cs:第160行
在System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String [] args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)
在System.Threading.ThreadHelper.ThreadStart()
如果删除OneToManyCascadeDeleteConvention
..
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
我不确定为什么我得到空引用异常。有人可以帮忙吗?谢谢!
答案 0 :(得分:0)
使用Fluent API(HasForeignKey
)定义外键。
public MessageHistoryConfiguration()
{
this.HasRequired(p => p.Message)
.WithMany(p => p.MessageHistories)
.HasForeignKey(p => p.MessageId)
.WillCascadeOnDelete(false);
//this.HasRequired(p => p.PostHistory)
// .WithMany(p => p.MessageHistories)
// .HasForeignKey(p => new { p.MessageBoardVersionId, p.PostId })
// .WillCascadeOnDelete(true);
}
第二个映射是多余的(因此我已将其注释掉)因为默认情况下所需的关系将默认进行级联删除。如果您确实要添加此映射,请包含HasForeignKey
,如上所示,以使配置与数据注释相匹配。
PostHistoryConfiguration
中的相同内容:
public PostHistoryConfiguration()
{
this.HasRequired(p => p.MessageBoardVersion)
.WithMany(p => p.PostHistories)
.HasForeignKey(p => p.MessageBoardVersionId)
.WillCascadeOnDelete(false);
}
在OnModelCreating
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Configurations.Add(new PostHistoryConfiguration());
modelBuilder.Configurations.Add(new MessageHistoryConfiguration());
}
对我来说,它无一例外地起作用。我不知道为什么会发生异常,它可能是EF中的一个错误。但另一方面,您的映射配置有点混乱,尤其是您使用Fluent API进行数据注释和(不完整)映射的混合。我会决定一个或另一个 - 至少每个实体,但最好是整个模型的Fluent API(因为在任何情况下都需要Fluent API才能禁用级联删除)。