I am making ajax calls to my webservice (using MS ajax framework - Telerik comps uses it actually). I am returning one of the Entity classes generated by the dbml. It used to work fine, but when I added the associations it started throwing an exception on the server, saying "a circular reference was detecting when serializing type "
I worked around it for now, but I'd really like to know what is happening. Thanks
This is because the relation is mapped with navigation properties both ways. ie you can use:
myCustomer.Orders
but also
order.Customer
You could try marking one of them non-public in the dbml, then if you need a public property, create it in the partial class, so you can mark the property with XmlIgnoreAttribute:
partial class Order
{
[XmlIgnore]
public Customer Customer
{
get { return InternalCustomer; }
set { InternalCustomer = value; }
}
}
Related
Here is my route
Route::get('desktops/{desktop}','DesktopsController#getdesktop');
Here is my controller method
public function getdesktop($identifier)
{
$desktop = Desktop::all()->where('identifier',$identifier);
$casings = $desktop->casings();
dd($casings);
}
I have added the App\Desktop, here is my casings method defined inside Desktop Class/Model
public function casings()
{
return $this->hasMany('App\Casing');
}
Now it seems to be working on tinker, but when I open it in my browser it throws an exception of method not found or to be exact BadMethodCallException, even though I have method defined inside the class. I can't seem to figure out the problem.
When you define the relationship in your model it is carried in to the eloquent object as a property rather than a function inside the collection.
As such you need to access it without the ():
$casings = $desktop->casings;
You can find out more about accessing the relationships in the docs.
I was using this
desktop = Desktop::all()->where('identifier',$identifier);
which was returning a record set, with multiple records. Even though there was only 1 record, it was treating it as a collection. So I tried changing
desktop = Desktop::all()->where('identifier',$identifier)->first();
which only fetched me a single record and it worked.
I am trying to de/seralize framework objects (no source code access) into JSON using jackson 2.
class Item {
public Item(Long id) {}
}
I found this Add annotation to a parameter on a new method created with Javassist but this solution is based on JavaAssist and does not fully apply :(
The underlying issue is the lack of DefaultConstructors which can be solved using the #JsonCreator annotation together with a matching #JsonProperty annotation for the parameter.
#JsonCreator
class Item {
public Item(#JsonProperty("id") Long id) {}
}
I managed to achieve this for one of the many item subclasses using a mixin class.
public abstract class ItemChildMixin {
#JsonCreator
public ItemChildMixin(#JsonProperty("objId") final Long objId) {
}
}
However, writing mixin classes for all the relevant objects with almost the same content seems the wrong approach, so I started looking at aspects.
Adding the Annotation to the classes in the Item's hierarchy was easy:
aspect DeclareJsonCreatorAspect {
declare #constructor: Item+.new(Long): #JsonCreator;
}
However, I cannot seem to find a way to add an annotation to the constructor parameters using Aspects!
Aspectj in Action as well as google did not provide an answer yet.
Is this at all possible?
Currently AFAIK AspectJ (currently v1.8.4) is unable to deal with annotations on method parameters, be it in pointcuts or in ITD (inter-type definition) statements.
I am sorry that I do not have any better news, but this is the status quo. If you have a chance to declare whole methods via ITD you can influence the full signature, but adding parameter annotations on existing methods is impossible today. You might also be able to also declare default constructors via ITD, if that helps. I am pretty sure there is a way to achieve what you want, just maybe not the way you imagine.
I am trying to make a deep copy of a L2S entity using the code below. I have the Serialization Mode of the .DBML set to Unidirectional. However, when I attempt to make a deep copy of an L2S entity, using the DeepCopy method shown below, I get an error saying the object isn't marked as serializable. Anyone know why?
public static T DeepCopy<T>(T obj)
{
object result = null;
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
result = (T)formatter.Deserialize(ms);
ms.Close();
}
return (T)result;
}
One of my L2S class definitions looks as follows:
[global::System.Data.Linq.Mapping.TableAttribute(Name="Polar.Recipe")]
[global::System.Runtime.Serialization.DataContractAttribute()]
public partial class RecipeRecord : INotifyPropertyChanging, INotifyPropertyChanged
DataContract attribute is required by DataContractSerializer but wont' work with other serializers like BinarySerializer, ViewStateSerializer and other serializers. In order to make them work You have to use Serializable attribute to apply to them. Now how to make that easy...
When I want to extend my Linq2Sql entities I usually abuse the fact that they are ALL partial classes. So I create file Linq2SqlExtensions.cs
public partial class LinqEntity
{
//extensions go here
}
and other extensions (like for example data context extensions). Now if You have many entities You can write a small program (even in powershell) to extract all class names out of Your Linq2Sql namespace/assembly (I pray You have them in another assembly) and create this file for You and automatically update it for You everytime YOu run it from VisualStudio Command line (or msBuild script).
something like
var entities = Assembly.Load("MyLinqAssembly").GetTypes().Where(p=> p.IsDefined(typeof(TableAttribute), true));
WriteEntityCsFile(entities);
Did you try adding Serializable attribute to your entity classes?
It's possible that DataContract attribute allows serialization only through WCF and other communication services, and not using BinaryFormatter.
Alternatively, try using DataContractSerializer instead BinaryFormatter.
I have a controller that is exported using MEF and loaded by the Controller factory.
[Export(Controller)]
public class MyController : Controller
{
private IRepository MyRepsoitory;
[ImportMany]
public IEnumerable<MyImportedItem> TestImportItems {get;set;}
public MyController([ImportMany]IEnumberable<MyImportedItem> items, [Import]IRepository repository)
{
// items here is always null
// However if I grab the container that the ControllerFactory used and tell it ComposeParts on this the TestImportItems will be filled with 50+ items
// repository however is instantiated appropriately.
GlobalItems.Container.ComposeParts(this);
//Now TestImportItems if filled but my items parameter alway null... how do I get constructor to fill
}
}
So MEF creates MyController but only creates the repository and sends null for the ImportMany even though it can fill the property later with the same Container.
What's also odd is if I do something that breaks one of the items the creation of MyConroller breaks in ControllerFactory.. as if it checks that is has parts for the constructor but never pushes them to the IEnumerable parameter.
What am I missing?
Obviously I have the parts available if the same Container works for .ComposingParts on (this) (and I reflected the catalog which has appropriate import/export Parts available at time of creating the Controller.
I could rewrite my class to use the filled Property but I would really like my importing constructor to get a filled collection.
UPDATE:
If I add a simple wrapper class for the import many MEF will load the [ImportMany] parameter.
So the following will fill the IEnumerable for me...
public MyController(TestImportClass test, [Import]IRepository repository)
{
//test.Items != null
}
public class TestImportClass
{
public IEnumberable<MyImportedItem> Items {get;set;}
[ImportingConstructor]
public TestImportClass([ImportMany]IEnumberable<MyImportedItem> items)
{
this.Items = items;
}
}
I am using a "Convention" system in my actual code to mark the Controller for Export. Maybe for some reason that is causing MEF to not understand the Import on initial Constructor Parameter? If that were the case though i am not sure why my IRepository always gets filled?
When you call ComposeParts, you pass objects which have already been constructed. It's not possible to call the constructor again on an existing object. (And in this case if you did you'd end up with infinite recursion). So ComposeParts doesn't satisfy constructor imports.
If your controller is pulled from the container some other way, and you put an ImportingConstructorAttribute on the constructor, the constructor imports should be satisfied.
Probably the convention system you are using doesn't support ImportMany in constructor arguments. Presumably the convention isn't applying to TestImportClass which is why the ImportMany works on that constructor.
We plan to have official convention model support in the next version of MEF, and we should be shipping a new codeplex release with a preview of this support soon.
I am porting an existing application from Linq to SQL to Entity Framework 4 (default code generation).
One difference I noticed between the two is that a foreign key property is not updated when resetting the object reference. Now I need to decide how to deal with this.
For example supposing you have two entity types, Company and Employee. One Company has many Employees.
In Linq To SQL, setting the company also sets the company id:
var company=new Company(ID=1);
var employee=new Employee();
Debug.Assert(employee.CompanyID==0);
employee.Company=company;
Debug.Assert(employee.CompanyID==1); //Works fine!
In Entity Framework (and without using any code template customization) this does not work:
var company=new Company(ID=1);
var employee=new Employee();
Debug.Assert(employee.CompanyID==0);
employee.Company=company;
Debug.Assert(employee.CompanyID==1); //Throws, since CompanyID was not updated!
How can I make EF behave the same way as LinqToSQL? I had a look at the default code generation T4 template, but I could not figure out how to make the necessary changes. It seems like a one-liner should do the trick, but I could not figure out how to get the ID property for a given reference.
From what I can see in the default T4 template, the foreign key properties of entities are not directly linked to the entity reference associated with the key.
Theres a couples to approach to your issue regarding migration from Linq to SQL to EF4. One of them would be to register to the AssociationChanged event of your associations so that it updates your field automatically. In your context, one approach could be something like like this :
// Extends Employee entity
public partial class Employee
{
private void CompanyChanged(Object sender, CollectionChangeEventArgs e)
{
// Apply reactive changes; aka set CompanyID
// here
}
// Create a default constructor that registers your event handler
public Employee()
{
this.CompanyReference.AssociationChanged += CompanyChanged;
}
}
Personally, if you want to limit the maintenance required to maintain this sort of logic, I'd suggest changing your T4 template (either change it yourself or find one) so that it sets the CompanyId when Company is changed as shown previously.
Gil Fink wrote a pretty good introdution to T4 templates with EF4, and you can look up Scott Hanselman wrapped a good bunch of useful links and ressources to work with T4 templates.
On a last note, unless I'm mistaken, accessing foreign keys directly as propeties of an entity is something new from EF3.5 to 4. In 3.5, only way you could access it was through the associated entity (Employee.Company.CompanyID). I believe the feature was added in EF4 so that you didn't have to load associations (using "include") in order to get the foreign key when selecting from the data store.
Perhaps EF's take on this would be, if you got the association, go through the association to get the ID, first and foremost. But that's just speculation as I got no quotes to back it up.
[EDIT 2010-06-16]:
After a quick readthrough and analysis of the edmx xml elements, I found one called ReferentialConstraint which appears to contain foreign key fields to a specfic FK_Relation.
Heres the code snippet to modify inside a default T4 edmx template, section Write Navigation Properties. (Template_RegionNavigationProperties), around line 388 of an unmodified template. Try to ignore the horrible formatting...
<#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> <#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#> <#=code.Escape(navProperty)#>
{
<#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value;
}
<#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
{
// edit begins here
if(value != null)
{
// Automatically sets the foreign key attributes according to linked entity
<#
AssociationType association = GetSourceSchemaTypes<AssociationType>().FirstOrDefault(_ => _.FullName == navProperty.RelationshipType.FullName);
foreach(var cons in association.ReferentialConstraints)
{
foreach(var metadataProperty in cons.FromProperties)
{
#>
this.<#=metadataProperty.Name#> = value.<#=metadataProperty.Name#>;
//this._<#=metadataProperty.Name#> = value._<#=metadataProperty.Name#>; // use private field to bypass the OnChanged events, property validation and the likes..
<#
}
}
#>
}
else
{
// what usually happens in Linq-to-SQL when an association is set to null
// here
}
// edit ends here
((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value = value;
}
}
I roughly tested it, but it's a given that theres some validation and such missing. Perhaps it could give you a tip towards a solution regardless.
Thanks for this solution. I've enhanced it (does not depend on specific naming conventions anymore) and encluded in a fix that also fixes an other issue with the Entity Framework template.
Check here for my solution and fixed code generation template