Entity framework 无法使用实体框架4.3.1在实体类型上设置字段/属性
我已经在.NET4.0解决方案中使用EntityFramework几个星期了。它是EF 4.3.1。我首先创建了数据库模式,并使用“EF4.x DbContext生成器”模板生成了实体对象 我在模式中有三个表,使用简单的CRUD方法都可以正常工作 我现在添加了第四个表“Subjects”,它有一个对现有表“SourceUri”的外键引用,这样一个SourceUri可以有0多个Subjects,而一个Subject正好有一个SourceUri 我已经更新了我的edmx模型,它看起来是正确的。然而,无论我尝试什么,我似乎都无法做到以下几点:Entity framework 无法使用实体框架4.3.1在实体类型上设置字段/属性,entity-framework,entity-framework-4,Entity Framework,Entity Framework 4,我已经在.NET4.0解决方案中使用EntityFramework几个星期了。它是EF 4.3.1。我首先创建了数据库模式,并使用“EF4.x DbContext生成器”模板生成了实体对象 我在模式中有三个表,使用简单的CRUD方法都可以正常工作 我现在添加了第四个表“Subjects”,它有一个对现有表“SourceUri”的外键引用,这样一个SourceUri可以有0多个Subjects,而一个Subject正好有一个SourceUri 我已经更新了我的edmx模型,它看起来是正确的。然而,
- 添加新的SourceUri记录
- 为新的SourceUri添加一个或多个主题
/// <summary>
/// Adds a new Source URI to the system
/// </summary>
/// <param name="sourceUri">The source URI to add</param>
/// <param name="subjectNames">List of subjects for this source URI, in order</param>
/// <returns>The added source URI</returns>
public SourceUri AddSourceUri(SourceUri sourceUri, IList<string> subjectNames)
{
try
{
_logger.Debug("Adding new source URI '{0}', with '{1}' subjects.", sourceUri.Uri,
subjectNames != null ? subjectNames.Count : 0);
LogSourceUriDetails(sourceUri, "Adding");
using (var dbContext = GetDbContext())
{
dbContext.SourceUris.Add(sourceUri);
dbContext.SaveChanges(); // this save succeeds
// add the subjects if there are any
if (subjectNames != null)
{
for (int i = 0; i < subjectNames.Count; i++)
{
Subject newSubject = new Subject()
{
DisplayOrder = i,
SourceUriId = sourceUri.SourceUriId,
SubjectText = subjectNames.ElementAt(i).Trim()
};
_logger.Debug("Adding new subject '{0}' to source URI '{1}'.", newSubject.SubjectText,
sourceUri.Uri);
dbContext.Subjects.Add(newSubject); // this line fails
dbContext.SaveChanges();
}
}
_logger.Debug("Successfully added new source URI '{0}' with '{1}' subjects. Source URI ID is '{2}'.",
sourceUri.Uri, subjectNames != null ? subjectNames.Count : 0, sourceUri.SourceUriId);
return sourceUri;
}
}
catch (Exception exception)
{
_logger.ErrorException(string.Format("An error occurred adding new source URI '{0}' with '{1}' subjects.",
sourceUri.Uri, subjectNames != null ? subjectNames.Count : 0), exception);
throw;
}
}
我在这个问题上反复讨论,并看到了几个稍有不同的例外。它们似乎都指向这样一个事实:SourceUri对象的Subjects导航属性在某种程度上是只读的或固定长度的(数组?)
生成的实体类如下所示:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CommentService.DomainObjects
{
using System;
using System.Collections.Generic;
public partial class SourceUri
{
public SourceUri()
{
this.Comments = new HashSet<Comment>();
this.Subjects = new HashSet<Subject>();
}
public long SourceUriId { get; set; }
public string Uri { get; set; }
public string Description { get; set; }
public System.DateTime DateCreated { get; set; }
public string AdminUser { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CommentService.DomainObjects
{
using System;
using System.Collections.Generic;
public partial class Subject
{
public Subject()
{
this.Comments = new HashSet<Comment>();
}
public long SubjectId { get; set; }
public long SourceUriId { get; set; }
public string SubjectText { get; set; }
public int DisplayOrder { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual SourceUri SourceUri { get; set; }
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CommentService.DomainObjects
{
using System;
using System.Collections.Generic;
using System.Linq; // added this
public partial class SourceUri
{
public SourceUri()
{
this.Comments = new HashSet<Comment>().ToList(); // added this
this.Subjects = new HashSet<Subject>().ToList(); // added this
}
public long SourceUriId { get; set; }
public string Uri { get; set; }
public string Description { get; set; }
public System.DateTime DateCreated { get; set; }
public string AdminUser { get; set; }
public virtual List<Comment> Comments { get; set; } // altered these to List
public virtual List<Subject> Subjects { get; set; } // altered these to List
}
}
//------------------------------------------------------------------------------
//
//此代码是从模板生成的。
//
//手动更改此文件可能会导致应用程序出现意外行为。
//如果重新生成代码,将覆盖对此文件的手动更改。
//
//------------------------------------------------------------------------------
命名空间CommentService.DomainObjects
{
使用制度;
使用System.Collections.Generic;
公共部分类SourceUri
{
publicsourceuri()
{
this.Comments=newhashset();
this.Subjects=newhashset();
}
公共长SourceUriId{get;set;}
公共字符串Uri{get;set;}
公共字符串说明{get;set;}
public System.DateTime DateCreated{get;set;}
公共字符串AdminUser{get;set;}
公共虚拟ICollection注释{get;set;}
公共虚拟ICollection主题{get;set;}
}
}
//------------------------------------------------------------------------------
//
//此代码是从模板生成的。
//
//手动更改此文件可能会导致应用程序出现意外行为。
//如果重新生成代码,将覆盖对此文件的手动更改。
//
//------------------------------------------------------------------------------
命名空间CommentService.DomainObjects
{
使用制度;
使用System.Collections.Generic;
公共部分类科目
{
公共主题()
{
this.Comments=newhashset();
}
公共长主体{get;set;}
公共长SourceUriId{get;set;}
公共字符串SubjectText{get;set;}
公共int显示顺序{get;set;}
公共虚拟ICollection注释{get;set;}
公共虚拟源URI源URI{get;set;}
}
}
为什么这样不行
快速列出我检查/尝试过的事项:
- 数据库模式看起来是正确的-我可以按预期使用SQL和主键插入记录,外键和标识的行为似乎是正确的
- 模型似乎正确地反映了数据库模式,包括PK标识(EntityKey=true,StoreGeneratedPattern=Identity)
- 我已经设法让EF将数据持久化到我的模式中,但在插入数据后,会引发一个异常,指出上下文可能不同步,这同样与无法更新SourceUri对象的Subjects导航属性有关
- 我已经尝试将主题添加到dbContext.Subjects集合,以及SourceUri.Subjects集合。我还尝试设置主题的SourceUri属性,而不是主题的SourceUriId属性
- 我已经弄清了这个问题的真相。问题行为是由SourceUri实体通过WCF web服务传递到方法中引起的。这意味着对象的ICollection属性被反序列化为一个数组,该数组具有固定长度,无法添加到
我已通过更改生成实体的模板来解决此问题,以便它生成集合显式列表的类,如下所示:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CommentService.DomainObjects
{
using System;
using System.Collections.Generic;
public partial class SourceUri
{
public SourceUri()
{
this.Comments = new HashSet<Comment>();
this.Subjects = new HashSet<Subject>();
}
public long SourceUriId { get; set; }
public string Uri { get; set; }
public string Description { get; set; }
public System.DateTime DateCreated { get; set; }
public string AdminUser { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CommentService.DomainObjects
{
using System;
using System.Collections.Generic;
public partial class Subject
{
public Subject()
{
this.Comments = new HashSet<Comment>();
}
public long SubjectId { get; set; }
public long SourceUriId { get; set; }
public string SubjectText { get; set; }
public int DisplayOrder { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual SourceUri SourceUri { get; set; }
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CommentService.DomainObjects
{
using System;
using System.Collections.Generic;
using System.Linq; // added this
public partial class SourceUri
{
public SourceUri()
{
this.Comments = new HashSet<Comment>().ToList(); // added this
this.Subjects = new HashSet<Subject>().ToList(); // added this
}
public long SourceUriId { get; set; }
public string Uri { get; set; }
public string Description { get; set; }
public System.DateTime DateCreated { get; set; }
public string AdminUser { get; set; }
public virtual List<Comment> Comments { get; set; } // altered these to List
public virtual List<Subject> Subjects { get; set; } // altered these to List
}
}
//------------------------------------------------------------------------------
//
//此代码是从模板生成的。
//
//手动更改此文件可能会导致应用程序出现意外行为。
//如果重新生成代码,将覆盖对此文件的手动更改。
//
//------------------------------------------------------------------------------
命名空间CommentService.DomainObjects
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;//添加了这个
公共部分类SourceUri
{
publicsourceuri()
{
this.Comments=new HashSet().ToList();//添加了这个
this.Subjects=new HashSet().ToList();//添加了这个
}
公共长SourceUriId{get;set;}
公共字符串Uri{get;set;}
公共字符串说明{get;set;}
public System.DateTime DateCreated{get;set;}
公共字符串AdminUser{get;set;}
公共虚拟列表注释{get;set;}//将其更改为列表
公共虚拟列表主题{get;set;}//将它们更改为列表
}
}
“有关详细信息,请参阅InnerException。”堆栈跟踪中的第一行表示。您可以这样做,并将内部异常消息添加到您的问题中吗?