6

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
}
KitKat
  • 63
  • 4
  • What project is causing the trouble, the silverlight project or de EF project? Can you also verify that you are not missing any files and does SL build without your WCF RIA Services link – Rik van den Berg Oct 25 '12 at 12:31
  • @Rikkos It was the SL Project, and it built fine if I remove all the relationships form my entity. See partial solution below. It was a combination of issues from using the TextTemplate in the toolkit merged with other solutions I had already tried. – KitKat Oct 25 '12 at 22:25

1 Answers1

6

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

mCasamento
  • 1,413
  • 1
  • 11
  • 21
  • Thank you very much for your response, however I still get the same result. I had been through those steps in my actual project and did not retry them in test until reading your post. My understanding was that EF picked up the naming conventions. But after explicitly defining the relationship I still get the same error. Any ideas? – KitKat Oct 25 '12 at 12:17
  • @KitKat You're welcome. mmm I rather think that your the EF5 metadataprovider isn't putting the needed AssociationAttribute. I'm going to edit my answer – mCasamento Oct 25 '12 at 13:45
  • I attempted this as well. Still a no-go. Examining the microsoft assemblies in the object browser, I just dont think the latest version if RIA Services supports code first anymore. I had to download a third party Nu Get package to get this far. WCFRIA.EntityFramework – KitKat Oct 25 '12 at 20:08
  • I would really love to get this resolved. Though right now I would be happy with a good tutorial on how to make an ObjectContext instead of a DbContext or how to create the proxy code manually. Any pointers along those lines? – KitKat Oct 25 '12 at 20:10
  • @KitKat I'm actually using dbcontext along with wcf ria services. Which CodeGenerator are you using ? Serverside are you referencing Microsoft.ServiceModel.DomainServices.Tools.TextTemplate ? – mCasamento Oct 25 '12 at 20:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18605/discussion-between-mcasamento-and-kitkat) – mCasamento Oct 25 '12 at 20:25
  • @mCasamento Would you please email or upload working example ? Shaahin69@gmail.com – Shahin Oct 27 '12 at 16:03
  • 1
    @shaahin ok, I'm thinking that this question worth a bit more detailed blog post from me, explaining how to deal such issues. I'll link it here when it will be done – mCasamento Oct 28 '12 at 08:47