Print Page | Close Window

Unable to hide one end of a many to many relation

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=1903
Printed Date: 21-Apr-2026 at 12:19pm


Topic: Unable to hide one end of a many to many relation
Posted By: NicoS
Subject: Unable to hide one end of a many to many relation
Date Posted: 21-Jun-2010 at 11:19am
Hi,
 
I'm in the process of evaluating DevForce for Silverlight.
In my EF model i have a direct many to many relation between two classes.(without having a intermidiate class, no payload)
I kept getting an exception :
object reference not set to an instance of an object at IdeaBlade.EntityModel.EntityReferenceBase.get_PropertyName()
in my Silverlight client when i wanted to display a master detail between the above classes.
 
So i started up a project with a NorthwindIB model which also has a many to many relationship between Employee and Territory without payload.
Showing a master detail between the Employee and Territory didnt give my any problems, so i wonderd why it didnt work in my model ?
 
In my model i wanted to "hide" navigation to lets say from Territory to Employee so i deleted the navigation property from Territory to Employees in EF.  I reproduced that step in the Northwind model and indeed the object reference not set was thrown again in the Silverlight client. After fixing the model with adding the navigation property back to the Territory class i decided to set the Getter and Setter for that navigation attribute to Employee in the EF model to private and later on protected. Testing the master/detail Silverlight client now throws an EntityServerException:
 
Attempt by method 'DynamicClass.ReadTerritoryFromXml(System.Runtime.Serialization.XmlReaderDelegator, System.Runtime.Serialization.XmlObjectSerializerReadContext, System.Xml.XmlDictionaryString[], System.Xml.XmlDictionaryString[])' to access method 'DevForceNW.Territory.get_Employees()' failed.
 
So im not sure how to hide the navigation from one end of a many to many relation now.
Any help, advice, best practice are welcome.
 
Excuse me if my english isnt correct.
TIA, Nico Schoemaker.
 
 



Replies:
Posted By: GregD
Date Posted: 22-Jun-2010 at 12:16pm
I'm not sure how you "put back" Territory.Employees; but if you did it properly, and had the Getter marked as Protected, then you should get a compile error upon any attempt to reference Territory.Employees: something like

"'Territory.Employees' is inaccessible due to its protection level",

or

"'Territory.Employees' cannot be used in this context because the get accessor is inaccessible"

Also, the Employees property should not show up on Territory in intellisense.


Posted By: NicoS
Date Posted: 22-Jun-2010 at 1:35pm
Hi Greg,
 
>I'm not sure how you "put back" Territory.Employees
I recreated the navigation property in the EF model setting it to the same association as Employee.Territories.
This was done correct because i could display the master-detail view again.
 
>Also, the Employees property should not show up........
Correct, The Territory.Employees isnt accessable any more after the deletion but that isnt the problem.
The problem is when it now try to access Employee.Territories i get the above mentioned exceptions.
 
Steps to reproduce:
NorthwindIB model, many to many relationship without payload between Employee.Territories and Territory.Employees.
Delete the Territory.Employees naviagation property from the EF model or set its Getters and Setters to private/protected.
Now display a master detail setup where Employee is the master showing Teritories as details.
This will throw the previous posted exceptions.
Without hiding/deleting the Territory.Employees it works fine.
 
So my question in this is how to hide Territory.Employees without getting exceptions when i try to access Employee.Territories ?
 
Below the master/detail XAML:

<toolkit:DataForm x:Name="EmployeeForm" ItemsSource="{Binding Employees}" CurrentItem="{Binding CurrentEmployee, Mode=TwoWay}" />

<sdk:DataGrid ItemsSource="{Binding ElementName=EmployeeForm, Path=CurrentItem.Territories}" />

 
 
Hth, Best regards,
Nico Schoemaker.
 
 
 
 


Posted By: GregD
Date Posted: 22-Jun-2010 at 2:24pm
Nico: I have duplicated your issue and am looking into it with the development staff. I'll get back to you when I know something more.


Posted By: GregD
Date Posted: 29-Jun-2010 at 12:05pm
You can do this as follows:
  1. Segregate your model into a separate assembly from your Silverlight application assembly.

  2. Add the following to attributes to the AssemblyInfo.cs (in the Properties folder) for the Silverlight assembly containing your domain model:

    [assembly: InternalsVisibleTo("System.Core, PublicKey=00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb77e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c123b37ab")]

    [assembly: InternalsVisibleTo("System.Runtime.Serialization, PublicKey=00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb77e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c123b37ab")]

  3. Set the scope of the M-M property you desire to hide to "Internal".

Silverlight apparently has to be able to reflect into your domain model assembly to see the hidden M-M property even when you are only accessing the public one.  The two attributes shown above give the System.Core and System.Runtime.Serialization assemblies the needed rights to reflect and see the Internal properties in your domain model assembly.

Private reflection simply isn't allowed in Silverlight, so scopes of Private and Protected can't be used for your purpose.

In the next release of DevForce, both attributes listed above will be automatically added to the project containing the EDM by the DevForce Silverlight Application project template.

Segregating Your Model Into a Separate Assembly

In the Learning Resources, you can see the sample app 030_BaseApps\SilverlightApps\Samples\200SLV_SeparateModelProjects for guidance. Basically the steps are as follows:
  1. Create a Windows Class library assembly and put your model there
  2. Reference the Windows Class Library assembly from your web project (where the Entity Data Model may have previously resided)
  3. Create a Silverlight Class Library. Add the generated model code file as a shared file to that assembly.
  4. Reference the Silverlight Class Library containing the shared model from your Silverlight application project.
  5. As stated at the beginning of this message, add the InternalsVisibleTo attributes to the AssemblyInfo.cs file in the Silverlight Class Library containing the shared model.
You'll need to put appropriate references in the two projects containing the domain model, but use the sample referenced above to see those.




Print Page | Close Window