Composition of composition not working - silverlight

I am currently using RIA services with an object containing a child containing itself a child and it's not working :-( !
I have an update method for the BaseObject and the FirstChild are correctly present in the client but it behaves as if I have no SecondChild object (the type is not event created on the client)...
Here are the classes:
[MetadataType(typeof(BaseObjectMetaData))]
public partial class BaseObject
{
internal class BaseObjectMetaData
{
[Include, Composition]
EntityCollection<FirstChild> FirstChilds { get; set; }
}
}
[MetadataType(typeof(FirstChildMetaData))]
public partial class FirstChild:
{
internal class FirstChildMetaData
{
[Include, Composition]
EntityCollection<SencondChild> SecondChilds { get; set; }
}
}

You need to also attribute your Collection property with the AssociationAttribute as well as include a ForeignKey on your entity class and reference it in the attributes ctor arguments, remember to include the DataMemberAttribute as well (entity framework already does this by default on generated members)
heres an article outlining it further

Related

Serialize a derived class without access to base class

I need to serialize a derived class in my Windows Phone 7 Project for tombstoning state.
But I don't have access to the code to the base class - exposed by a Library -.
//don't have access to this class
public class A
{
public string member1 {get;set;}
}
[DataContract]
public class B : A
{
public B(){}; //CTOR
[DataMember]
public string member2 {get;set;}
}
When the system try to serialize (I save it to PhoneApplicationPage.State => so it's auto serializing) : it's not working, the exception (InvalidDataContractException) says "Type 'B' cannot inherit from a type that is not marked with DataContractAttribute or SerializableAttribute. Consider marking the base type 'A' with DataContractAttribute or SerializableAttribute, or removing them from the derived type."
Should I implement a custom serializer ? How can I do that (in Windows Phone 7)
Rather than derive from the library class, you could have a member variable that of that type and expose the properties of the library class member via custom getters and setters:
[DataContract]
public class MyClass
{
BaseClass Wrapped { get; set; }
public MyClass()
{
Wrapped = new BaseClass( );
}
[DataMember]
public string member1
{
get { return Wrapped.member1; }
set { Wrapped.member1= value; }
}
}

How to change exported property through MEF?

I'm studying MEF, and try to use Export attribute to export a property, and import it in an other class.
But my problem is that I want to change this property and the other class can import a new value.
For example,
[Export]
public class A{
[Import("Notes")]
public string Description{get;set;}
}
[Export]
public class B{
[Export("Notes")]
public string Text{get;set;}
}
I want once I change the Text of class B, the A.Description can get changed too.
So, how can I implement this?
Any good idea?
This approach would work for most reference type but not with string which is immutable. This means that after you change the value of B.Text, the objects referenced by A.Description and B.Text will no longer be the same (you can use Object.ReferenceEquals to test this).
One way to do what you are after using MEF is to export/import a method instead of the property:
[Export]
public class A
{
public string Description { get { return GetDescription(); } }
[Import("GetNotes")]
Func<string> GetDescription;
}
[Export]
public class B
{
public string Text { get; set; }
[Export("GetNotes")]
string GetText()
{
return Text;
}
}
Finally note that there are other ways to do this. The most common in .NET is with events.

Bind data from WCF Ria Services to data grid Entity Framework Code First

I've created simple POCO class like this :
public class Entity
{
public int Id { get; set; }
public bool IsActive { get; set; }
}
And this is my EF DbContext :
public class SampleContext:DbContext
{
public DbSet<Entity> Entities { get; set; }
}
I defined sample logic layer like this :
public class EntityTask : IEntityTask
{
#region Implementation of IEntityTask
public IEnumerable<Entity> GetAll()
{
var contex = new SampleContext();
return contex.Entities.ToList();
}
#endregion
}
public interface IEntityTask
{
IEnumerable<Entity> GetAll();
}
This is DomainService class that defined in server project :
[EnableClientAccess()]
public class CrudService : DomainService
{
private readonly IEntityTask _entityTask;
public CrudService(IEntityTask entityTask)
{
_entityTask = entityTask;
}
public IQueryable<Entity> GetAll ()
{
return _entityTask.GetAll().AsQueryable();
}
}
After these steps I don't know how to bind data to DataGrid in silverlight project.
I've checked many links on the web but many of them use wizard to bind data to datagrid.
How do I bind entities to DataGrid ?
Start marking your entity with the KeyAttribute (probably on the Id property) then
you must indicate to msbuild how to create the proxy counterpart of your service (named the DomainContext): in your silverlight project under properties tab
select your "server side" project and build the solution.
Client side a proxy will be generated, check it by looking in the client project (be sure to press "Show all files in Solution Explorer" and look for something similar to the image below
Under the Generated_Code hidden folder you'll find your DomainContext.
From now on it should be pretty straightforward to load and bind your data. Look at the excellent blog posts series by Brad Abrams here, you'll find everything you need.

MEF Importing ViewModel that needs data, to View for Silverlight

I'm not sure the best way to get this accomplished. Here's my view:
public partial class MyPage : Page
{
[Import]
public MyVM ViewModel
{
get { return DataContext as MyVM ; }
set { DataContext = value; }
}
public String EventName { get; set; }
public MyPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
}
// Executes when the user navigates to this page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{ }
}
And my VM:
[Export]
public class MyVM : ViewModelBase
{
public MyVM ()
{
}
}
This works great. However, I need to get data from either the viewmodel that has my string, or the URL. Either way, I'm not sure the best way to get the string to MyVW using MEF.
I thought ok I'll use Messaging from MVVMLight, but the MyVM class isn't instantiated yet to receive the broadcast from the other ViewModel. So then I thought well, I'll try this:
[Export]
public class MyVM : ViewModelBase
{
public MyVM ([Import("hello")]string hello)
{
}
}
and then put this in the view:
[Export("hello")]
public String MyHello { get; set; }
but that gave me an error. Cannot call SatisfyImports on a object of type 'Form A' because it is marked with one or more ExportAttributes.
So what's the best way to accomplish this?
To share data between views I usually inject a SharedData object into my ViewModels.
[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
public ISharedData SharedData { get; set; }
I'm also using the Caliburn Micro framework so I'm not passing data around via the URL querystring. By convention CM will parse out URL parameters and inject them into properties on your VM but I'm not sure if this functionality only applies to Windows Phone development.
from here
Examine the Page’s QueryString. Look
for properties on the VM that match
the QueryString parameters and inject
them, performing the necessary type
coercion.
When you say you want to possibly pass data from the view to the vm, that should happen through databinding.

Entity Framework / RIA Services Include not working

I've got a SL4 / WCF RIA Services / EF 4 application. I'm having trouble getting my Included entity into my SL4 data context.
In the server side service portion of the application, this is my method:
[Query(IsDefault = true)]
public IQueryable<ToolingGroup> GetToolingGroups()
{
var groups = this.ObjectContext.ToolingGroups.Include("MetaData").OrderBy(g => g.Name);
return groups; //breakpoint set here
}
I assigned it to the var groups to allow it to be inspected before the method returns. If I set a breakpoint before the method returns and add a line to my Watch window the MetaData is there:
groups.First().MetaData
When I let the method return and check it in the silverlight ui completed event MetaData is null.
void loadOperation_Completed(object sender, System.EventArgs e)
{
grid.ItemsSource = _toolingContext.ToolingGroups;
UpdateUI(); //breakpoint set here
}
When I do this in my watch window MetaData is null:
_toolingContext.ToolingGroups.First().MetaData
I checked to make sure the ToolingGroup returned by the call to .First() in both cases was the same entity and it was.
Why is MetaData lost (eg. null) between the service method and my ui method?
SOLUTION:
// The MetadataTypeAttribute identifies ToolingGroupMetadata as the class
// that carries additional metadata for the ToolingGroup class.
[MetadataTypeAttribute(typeof(ToolingGroup.ToolingGroupMetadata))]
public partial class ToolingGroup
{
// This class allows you to attach custom attributes to properties
// of the ToolingGroup class.
//
// For example, the following marks the Xyz property as a
// required property and specifies the format for valid values:
// [Required]
// [RegularExpression("[A-Z][A-Za-z0-9]*")]
// [StringLength(32)]
// public string Xyz { get; set; }
internal sealed class ToolingGroupMetadata
{
// Metadata classes are not meant to be instantiated.
private ToolingGroupMetadata()
{
}
public int Id { get; set; }
[Include] // Added so MetaData gets serialized
public MetaData MetaData { get; set; }
public Nullable<int> MetaDataId { get; set; }
public string Name { get; set; }
public ToolingCategory ToolingCategory { get; set; }
public int ToolingCategoryId { get; set; }
public EntityCollection<ToolingType> ToolingTypes { get; set; }
}
}
There are two layers at play here, EF and RIA Services. You've handled the EF part. Now you need to tell RIA services to include that property when it serializes your entities across the wire. In your metadata for the entity, add the [Include] attribute. Like this...
[MetadataType(typeof(ToolingGroup.MetaData)]
public partial class ToolingGroup {
private class MetaData {
// adding this attribute tells RIA services
// to also send this property across
[Include]
public MetaData MetaData { get; set; }
}
}
It's a bad coincidence that your type is called "Metadata", the ToolingGroup.MetaData class is the metadata that RIA services uses.

Resources