EF5代码优先和RIA服务Silverlight“对象引用未设置为对象的实例”错误构建客户端 [英] EF5 Code First and RIA Services Silverlight "Object reference not set to an instance of an object" error building client

查看:188
本文介绍了EF5代码优先和RIA服务Silverlight“对象引用未设置为对象的实例”错误构建客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用RIA服务在silverlight中为实体框架5使用Code First设计一个新项目。我已经创建了一个测试项目,由于我遇到的一些问题,并将发布下面的代码。也就是说,当我尝试构建应该生成客户端代理类的silverlight客户端项目时,我会得到一个对象引用未设置为对象的实例错误。



只要清楚,运行或调试应用程序时,但是在构建它时,这个错误不是。



我已经孤立,只有在我的Code First课程中定义了任何导航属性/外键时才会发生这种情况。



今晚的任何帮助将不胜感激。 >

  public class Person 
{
public int PersonId {get;组; }
public string FirstName {get;组; }
public string LastName {get;组; }
public DateTime? BirthDate {get;组; }

public virtual List< Character>人物{get;组; }
}

public class Character
{
public int CharacterId {get;组; }
public int PersonId {get;组; }
public virtual Person Person {get;组; }
public string CharacterName {get;组; }
}

public class CharacterDbContext:DbContext
{
public DbSet< Person>人{get;组; }
public DbSet< Character>人物{get;组;

public CharacterDbContext()
{
if(HttpContext.Current == null)
{
Database.SetInitializer< CharacterDbContext>(null);
}
}
}

[EnableClientAccess]
public class CharacterDbService:DbDomainService< CharacterDbContext>
{
#region具有Persons的上下文属性的Person的基本方法

[查询]
public IQueryable< Person> GetPersons()
{
return DbContext.Persons;
}

[插入]
public void InsertPerson(Person entity)
{
DbEntityEntry< Person> entityEntry = DbContext.Entry(entity);
if(entityEntry.State!= EntityState.Detached)
{
entityEntry.State = EntityState.Added;
}
else
{
DbContext.Persons.Add(entity);
}
}

[更新]
public void UpdatePerson(Person entity)
{
DbContext.Persons.AttachAsModified(entity,ChangeSet .GetOriginal(entity),DbContext);
}

[删除]
public void DeletePerson(Person entity)
{
DbEntityEntry< Person> entityEntry = DbContext.Entry(entity);
if(entityEntry.State!= EntityState.Deleted)
{
entityEntry.State = EntityState.Deleted;
}
else
{
DbContext.Persons.Attach(entity);
DbContext.Persons.Remove(entity);
}
}

#endregion

#region使用字符的上下文属性的字符的基本方法

[查询]
public IQueryable< Character> GetCharacters()
{
return DbContext.Characters;
}

[插入]
public void InsertCharacter(Character entity)
{
DbEntityEntry< Character> entityEntry = DbContext.Entry(entity);
if(entityEntry.State!= EntityState.Detached)
{
entityEntry.State = EntityState.Added;
}
else
{
DbContext.Characters.Add(entity);
}
}

[更新]
public void UpdateCharacter(Character entity)
{
DbContext.Characters.AttachAsModified(entity,ChangeSet .GetOriginal(entity),DbContext);
}

[删除]
public void DeleteCharacter(Character entity)
{
DbEntityEntry< Character> entityEntry = DbContext.Entry(entity);
if(entityEntry.State!= EntityState.Deleted)
{
entityEntry.State = EntityState.Deleted;
}
else
{
DbContext.Characters.Attach(entity);
DbContext.Characters.Remove(entity);
}
}

#endregion
}


解决方案

您的外键字段未映射,因此代理代码生成器无法解释(编译时调用构建代理的代码段)。 br>
你应该放在你的DbContext东西

 保护覆盖void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity< Character>()
.HasRequired(x => x.Person)
.WithMany(x => x .Characters)
.HasForeignKey(x => x.PersonId);
}

此外,我建议您更改您的
public virtual List< Character>人物{get;组; }

to
public virtual ICollection< Character>人物{get;组; } ,因为我不知道代理生成器(和EF)是否会正确地映射该列表。

编辑:

我认为EF Metadataprovider在描述中没有提供正确的属性。

在Character.CharacterId上放置一个 KeyAttribute Person.PersonID也可以通过Character.Person添加这一行

  [Association(Character_Person,PersonId,PersonId ,IsForeignKey = true)] 

而这一个超过Person.Characters

 关联(Character_Person,PersonId,PersonId)]< br> 

编辑:

与KitKat聊天后终于找到了问题。在代理生成期间,对Assembly.GetExportedTypes的调用坠毁抱怨需要EF 4.1。
简单放置

 < runtime> 
< assemblyBinding xmlns =urn:schemas-microsoft-com:asm.v1>
< dependentAssembly>
< assemblyIdentity name =EntityFrameworkpublicKeyToken =b77a5c561934e089culture =neutral/>
< bindingRedirect oldVersion =0.0.0.0-5.0.0.0newVersion =5.0.0.0/>
< / dependentAssembly>
< / assemblyBinding>



在相关配置中



注意:在这个链接我的博客帖子更好地解释了如何处理EF5代码和WCF Ria服务


I am working on setting up a new project using Code First for entity framework 5 in silverlight using RIA services. I have created a test project due to some issues I have encountered and will post the code below.

Namely, I get an 'Object reference not set to an instance of an object' error anytime I attempt to build the silverlight client project which should generate the client proxy classes.

Just to be clear, this error is not while running or debugging the application, but when building it.

I have isolated that this only happens if I have any navigation properties/Foreign Keys defined on my Code First classes.

Any help tonight would be greatly appreciated.

    public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime? BirthDate { get; set; }

    public virtual List<Character> Characters { get; set; }
}

public class Character
{
    public int CharacterId { get; set; }
    public int PersonId { get; set; }
    public virtual Person Person { get; set; }
    public string CharacterName { get; set; }
}

public class CharacterDbContext : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public DbSet<Character> Characters { get; set; }

    public CharacterDbContext()
    {
        if (HttpContext.Current == null)
        {
            Database.SetInitializer<CharacterDbContext>(null);
        }
    }
}

[EnableClientAccess]
public class CharacterDbService : DbDomainService<CharacterDbContext>
{
    #region Basic Methods for Person with the context property of Persons

    [Query]
    public IQueryable<Person> GetPersons()
    {
        return DbContext.Persons;
    }

    [Insert]
    public void InsertPerson(Person entity)
    {
        DbEntityEntry<Person> entityEntry = DbContext.Entry(entity);
        if (entityEntry.State != EntityState.Detached)
        {
            entityEntry.State = EntityState.Added;
        }
        else
        {
            DbContext.Persons.Add(entity);
        }
    }

    [Update]
    public void UpdatePerson(Person entity)
    {
        DbContext.Persons.AttachAsModified(entity, ChangeSet.GetOriginal(entity), DbContext);
    }

    [Delete]
    public void DeletePerson(Person entity)
    {
        DbEntityEntry<Person> entityEntry = DbContext.Entry(entity);
        if (entityEntry.State != EntityState.Deleted)
        {
            entityEntry.State = EntityState.Deleted;
        }
        else
        {
            DbContext.Persons.Attach(entity);
            DbContext.Persons.Remove(entity);
        }
    }

    #endregion

    #region Basic Methods for Character with the context property of Characters

    [Query]
    public IQueryable<Character> GetCharacters()
    {
        return DbContext.Characters;
    }

    [Insert]
    public void InsertCharacter(Character entity)
    {
        DbEntityEntry<Character> entityEntry = DbContext.Entry(entity);
        if (entityEntry.State != EntityState.Detached)
        {
            entityEntry.State = EntityState.Added;
        }
        else
        {
            DbContext.Characters.Add(entity);
        }
    }

    [Update]
    public void UpdateCharacter(Character entity)
    {
        DbContext.Characters.AttachAsModified(entity, ChangeSet.GetOriginal(entity), DbContext);
    }

    [Delete]
    public void DeleteCharacter(Character entity)
    {
        DbEntityEntry<Character> entityEntry = DbContext.Entry(entity);
        if (entityEntry.State != EntityState.Deleted)
        {
            entityEntry.State = EntityState.Deleted;
        }
        else
        {
            DbContext.Characters.Attach(entity);
            DbContext.Characters.Remove(entity);
        }
    }

    #endregion
}

解决方案

Your foreign key fields aren't mapped, thus they can't be interpreted by the proxy code generator (the piece of code called to build your proxy during compilation).
You should put in you DbContext something like

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
      modelBuilder.Entity<Character>()
          .HasRequired(x=> x.Person)
          .WithMany(x=> x.Characters)
          .HasForeignKey(x=> x.PersonId);
 }

also, I suggest you to change your
public virtual List<Character> Characters { get; set; }
to
public virtual ICollection<Character> Characters { get; set; } , because I'm not sure if the proxy generator (and EF too) will map that list correctly.
EDIT:
I'm thinking that the EF Metadataprovider isn't supplying the correct attribute in description.
Put a KeyAttribute over the Character.CharacterId and Person.PersonID, also, add this line over Character.Person

[Association("Character_Person", "PersonId", "PersonId", IsForeignKey = true)]

and this one over Person.Characters

Association("Character_Person", "PersonId", "PersonId")]<br>

EDIT:
After chat with KitKat we finally found the problem. During proxy generation a call to Assembly.GetExportedTypes crashed complainig it need EF 4.1. Simple putting

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
  </dependentAssembly>
</assemblyBinding>

in the related config did the tricks

Note: at this link ther's blog post from mine that better explains how to deal with EF5 Code first and WCF Ria Services

这篇关于EF5代码优先和RIA服务Silverlight“对象引用未设置为对象的实例”错误构建客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆