Search code examples
silverlightwcf-ria-services

Ria Service: Navigation Property is null


For example I have two entities

Class A
{
 public Guid Id {get;set;}
 public Guid BId {get;set;}
 public B InstanceB {get;set;}
}

Class B
{
 public Guid Id {get;set}
}

B is related to A, on my silver light application I am creating a new instance of A, and also a new instance of B. The new instance of B does not exist yet. But I need the instance of B on my service.

Can I do this without Entity or Association with Ria Service?

Edit:

My Class A :

public partial class lSync{

        // Metadata classes are not meant to be instantiated.
        private lSync() {
        }

        public string ConflictMessage { get; set; }

        public DateTime DateInserted { get; set; }

        public Guid vValuesId { get; set; }

        public Guid ID { get; set; }

        public bool IsConflict { get; set; }

        public bool IsReadyToSync { get; set; }

        public Guid SyncSet { get; set; }

        public vValues vValues { get; set; }

    }

My Ria Service:

[Invoke] public lSync[] SynchvValuesFromClient(lSync[] syncs) {

        bool noConflict = true;
        foreach (lSync sync in syncs) {
            var servervValue = GetvValuesByID(sync.vValuesId).FirstOrDefault();
            var queuevValues = sync.vValues; //sync.vValues here is null, but my sync.vValuesId is not
            if (servervValue== null) {
                InsertvValues(queueValue);
            }
            else {
                if (servervValue.IsServerConflict(queueValue)) {
                    sync.IsConflict = true;
                    sync.ConflictMessage = "Conflict";
                    noConflict = false;
                    break;
                }
                if (!servervValue.AreValuesEqual(queueValue)) {
                    UpdatevValues(queueValue);
                }
            }
        }

        if (noConflict) {
            this.ObjectContext.SaveChanges();
        }
        return syncs;
    }


    public IQueryable<vValues> GetvValuesByID(Guid ID) {
        return ObjectContext.vValues.Where(t => t.ID == ID);
    }


    public void InsertvValues(vValues model) {
        model.ServerDate = DateTime.UtcNow;
        if ((model.EntityState != EntityState.Detached)) {
            this.ObjectContext.ObjectStateManager.ChangeObjectState(model, EntityState.Added);
        }
        else {
            this.ObjectContext.vValues.AddObject(model);
        }
    }


    public void UpdatevValues(vValuesmodel) {
        model.ServerDate = DateTime.UtcNow;
        this.ObjectContext.vValues.AttachAsModified(model,               this.ChangeSet.GetOriginal(model));
    }

:(


Solution

  • Edit

    The order is wrong of your method :) Make an instance of the service before creating instances of the Entities.

    It should be:

    public void SyncToServer() { 
      ContextService service = new ContextService();
      var instanceA = new A(); 
      instanceA.InstanceB = new B(); 
      service.SubmitChanges(); //service.SaveChanges() for LinqToEntities
    }
    

    Are you reloading after a submit because only adding the [Include] attribute in the DomainService MetaData won't work. You need to do this in the DomainService for LinqToSql

    public A GetA()
    {
      DataLoadOptions dlo = new DataLoadOptions();
      dlo.LoadWith<A>(a => a.InstanceB);
      this.DataContext.LoadOptions = dlo;
      return this.DataContext.APlural.FirstOrDefault( ); //don't know the plural of A.
    }
    

    LinqToEntities:

    public A GetA()
    {
      return this.MyEntitiesContext.APlural.Include( "instanceB" ).FirstOrDefault( ); //don't know the plural of A.
    }