I am mapping some pre-existing Business Objects to our database using Entity Framework. These object were originally using a home-grown data access method, but we wanted to try out Entity Framework on it now that it is using Code-First. It was my expectation that this would be fairly simple, but now I am having some doubts.
I am trying to use only attributes to accomplish this so that I don't have some of the mapping here, some of it there, and still more of it over there....
When I query for entities, I am getting System.Data.Entity.DynamicProxies.MyClass_23A498C7987EFFF2345908623DC45345 and similar objects back. These objects have the data from the associated record there as well as related objects (although those are DynamicProxies also).
What is happening here? Is something going wrong with my mapping? Why is it not bringing back MyBusinessObject.MyClass instead?
That has nothing to do with mapping. Those types you see are called dynamic proxies. EF at runtime derives class from every type you map and use it instead of your type. These classes has some additional internal logic inside overriden property setters and getters. The logic is needed for lazy loading and dynamic change tracking of attached entities.
This behaviour can be turned off in context instance:
context.Configuration.ProxyCreationEnabled = false;
Your navigation properties will not be loaded automatically once you do this and you will have to use eager loading (Include method in queries) or explicit loading.
Related
i'm just new to ASP.NET and other things with it.. i am using automapper in entity framework which is giving the ERROR.......
this occurs when i tried to get the desired data with JSON response...
System.Data.Entity.DynamicProxies.Account_C2A5EBE3CC4467F8B34569FAEB8687C41333F5D82DB38AC1D2E21FC5F8A47193'.]
i have tried many resources on stackoverflow and on other platforms also but there is no solid solution to this problem.
i have turned on LAZY LOADING using virtual keyword in MODELS.
i don't want to turn off lazy loading using ..
Configuration.ProxyCreationEnabled = false;
i am searching for the other solution to load all the data using the lazy loading ..
If i am going to off lazy loading then other headaches are to face on.
please help me out Seniors ...........
Two options:
Do not serialize the entire entity. Instead, convert it to a more simple class, and then serialize that object. I recommend you to use AutoMapper for object conversion.
If you use Json.Net, you can add the JsonIgnore attribute on top of the properties you want to avoid.
My recommendation is the first option. I think is a good idea to return only the objects you really need. For that purpose, you should have simple model objects and a mapper that transforms between your entities and this model classes. If, for example, all your entity objects are completely connected, there can be the case that you will serialize the entire database, which is not desirable. Try to move out the Entities from the presentation layer.
An NSCollectionViewItem is derived from NSViewController. I use it as a prototype in an NSCollectionView. It has a property called RepresentedObject. Normally, I would use something like
var set = this.CreateBindingSet<DevViewController, DevViewModel> ();
set.Bind (devTextField).To (vm => vm.Text);
set.Bind (devTextView).To (vm => vm.BigText);
to bind UI elements with the vm. In the case of the NSCollectionViewItem, I want to bind to properties in the RepresentedObject. How do I do this?
NSCollectionView.Content takes NSObject[]. I'm currently taking my List and making an NSObject[] where each item in there is NSObject.FromObject(myClass) - which itself may not be the right approach.
Thanks in advance!
Update. It seems that if I can make my NSObject a KVO'd object ala http://cocoa-mono.org/archives/153/kvc-kvo-and-cocoa-bindings-oh-my-part-1/ that the bindings would automatically work.
The general approach of MvvmCross and its binding layer is that:
it tries to work with native controls,
but it also tries to encourage you to keep your ViewModel objects independent and unaware of any native choices.
So if you're trying to use a native control which requires you to supply a NSObject[] array, and you want to display (say) a list of customers, then a reasonable design choice within MvvmCross would be:
within the ViewModel:
to use a Customer object which provides INotifyPropertyChanged
to supply a List<Customer> as a parameter on your ViewModel
within the View:
to supply a NSObject[]
somewhere between the two
find:
a way of mapping your List<> to an []
and find a way of mapping your Customer to an NSObject
this can be found either:
using inheritance of the View and providing a custom C# property for binding
or using a custom binding
or using a value converter
The challenge of mapping the Customer to an NSObject is a particularly interesting one. If your end view is looking for KVO type functionality then I believe the conversion can be done by using a small Converter class which maps ValueForKey/SetValueForKey to their .Net reflection equivalent, and which maps INotifyPropertyChanged events to their DidChangeValue NSObject equivalent. I've not personally done this... but it feels like it should be doable, and (with a little caching of PropertyInfo objects) it should probably be reasonably efficient too.
Some final notes:
if you are marshalling a lot of calls between KVO and .Net reflection and this does impact your application's performance, then you may find using Rio style Field binding might be a faster experience, or you may find that it's faster to write hard-coded non-reflection based wrappers for your specific types.
if your ViewModel collection is mutable - e.g. it supports INotifyCollectionChanged then there may also be other interesting and reasonably efficient ways you can respond to the collection change events - although your view may not support these particularly 'beautifully' without some additional animation work.
I get the exception 'The entity type [TYPE] is not part of the model for the current context.' when trying to run my application.
My best guess so far is that it doesn't recognize my type as a type that it has mapped. This could very well be since it is a type loaded at runtime. This type comes from a different assembly.
How does EF: CF find all it's entities to map, and how can I make it find my types ?
EF is not designed to support this feature directly. EF is ORM and ORM is mostly created for purpose when you specify types you want to use and map at design time and simply use them at runtime. It doesn't mean that it is not possible to create types at runtime (with code mapping) but it is much more complex.
Context must know about all types it should map and about their mapping. If you create context with no reference to your new type it simply doesn't know about it. How to solve it? I can think about two options:
Emit context code as well and make sure that emitted context code contains public property of type DbSet<YourEmittedEntityType> (to use default mapping conventions) or emit OnModelCreating method as well to specify custom mapping.
Emit configuration (derived from EntityTypeConfiguration<YourEmittedEntityType>) class for your new entity as well. This class will specify mapping of new entity to your database table. Once you have your configuration you can manually create DbModelBuilder register all necessary entity type configuration including your new ones created at runtime, build DbModel, compile it and use DbCompiledModel to construct new instance of the DbContext. Just make user you cache DbCompiledModel for subsequent usages because its construction is very time consuming.
In both cases make sure that table used to persist and retrieve new entity is already created and turn off any database initializers - you must maintain your database manually.
Sure this is only the first step. Now you need to emit / generate code which will use your new entity and context - be aware that EF doesn't work with interfaces and inheritance is handled specially so in the most scenarios you need code working with your emitted type directly.
I have a LINQ to SQL entity that I will be serializing and returning as JSON over a webservice call.
There is one property on that entity that I would like not to be serialized. For this, there is generally the [ScriptIgnore] attribute, which works exactly the way I want if I manually add that to the designer.cs file.
Now, since the designer file is automatically generated, I would prefer not having to manually edit it, as any changes could easily be overwritten. My question is thus: is there any way to annotate the property so that it is excluded upon serialization, directly in the DBML editor?
If the answer is no; are there any solutions to this that are neater than manually setting the property to null before serializing it, or returning an anonymous type identical except for that one property? In MVC.NET, is there any way to pass parameters to the JSON() method to modify its behavior, perchance?
My apologies if this has been asked before - I'd expect it to be a common question, but I couldn't find anyone like it.
All the DBML generated classes are partial classes so that you can extend them in another file. The DBML designer will only alter classes in the Designer.cs file. Remove the property from the DBML designer and put it in a partial class in another file. You can then add whatever extra attributes you wish, and the DBML designer will leave it alone. You will have to manually manage this property and update it to match any database changes, but I think that is probably a price worth paying if it solves your problem.
If you will have no success with partial classes (which is probably the best way), then you can just serialize the date yourself. It is known that ASP.NET MVC use JavaScriptSerializer to serialize the data. The JavaScriptSerializer have simple and nice customization features like JavaScriptConverter and you can very easy convert the object in something less standard (see use Attr tags for json? for example or all other topics).
To be the most conform to the standards you can define a class derived from JsonResult (for example like here ASP.net MVC returning JSONP or http://dev.qsh.eu/Blogs/Dmitry-P/January-2010/ASP-NET-MVC-Tip--3.aspx) and save serialized data in context.HttpContext.Response directly with a Write method. Then you are absolutely free how you serialize the data to JSON.
Instead of using the partial class answer above you could try going into the DBML designer and setting the access modifier of the property from public to internal. I did this on table to table relationship properties and doing so worked for me to eliminate circular references when serializing my objects to JSON.
If I try to serialize a linq-to-sql entity, will it by default serialize only the primitive fields or will it try to access the relationship fields as well? If it tries to grab relationship fields, is there a way to override this?
Which serializer are you using?
The DataContractSerializer will
include loaded relationships but not
those that are not yet loaded / null.
The XmlSerializer tend to choke on relationships if they are bidirectional (i.e. entity A points to entity B which in turn points back).
The binaryformatter ... I never got that one to work properly with L2S entity objects having relationships to other entities. Long time since I tried though, so maybe I just did something wrong...
Another point to add to the accepted answer:
Relationships that are not collections will never be serialized by DataContractSerializer (whether they are loaded or not), because no DataMember attribute is generated for them from the .dbml file.
I found here an explanation by then-at-Microsoft Daniel Simmons:
The issue here is that prior to SP1 there was really no good way with DataContract serialization to handle graphs of objects that had cycles. As a result for LINQ to SQL the compromise decision was made to allow users to opt-in for uni-directional serialization and to only serialize collections not references. This mechanism doesn't work well for cases where you really want to serialize a reference (like your scenario above), but it at least gets you going for some common scenarios.
In SP1 new support was added to WCF which enables DataContract serialization to deal with cycles, but it is something you must opt-in to by changing some of your DataContract attributes and potentially also making changes to your collection and reference class implementations to properly handle the serializaiton and especially the deserialization behaviors of WCF. In the Entity Framework the changes were made to take advantage of these new features since it had not yet released its very first version, but Linq to SQL only had a small service-pack upgrade in sp1 and it was not modified to take advantage of this capability.
I have not experimented with this on L2S, but it might be possible to generate your own classes which work with L2S and have the right support for WCF serialization with cycles.
Danny