I have a circular object reference which stops an object from being serialized into json. I was trying to use ScriptIgnoreAttribute on the property that is causing problems, but it didn't seem to work. I believe that's because I'm using EF convention with virtual keyword:
[ScriptIgnore]
public virtual SomeObject SomeObject { get; set; }
The other side of this relationship looks like this
public virtual ICollection<OtherObject> OtherObjects { get; set; }
I have no additional mappings.
How can I resolve this?
The problem is that each of the OtherObject objects has a back reference to SomeObject, which in turn has a collection of OtherObject, etc.
I would recommend creating a viewmodel class which contains only the properties you need. Then, map your entity to the viewmodel class. Return the viewmodel class instance instead of the raw entity.
The other alternative is to tell the json serializer to stop serializing circular references. I prefer the first approach though.
You can also influence EF behavior (ex. disable lazy loading by removing the virtual keyword) or by changing the query.
But really, I prefer the viewmodel approach. I find that using viewmodels solves not only this but other problems as well.
I took the approach of ignoring the associated objects. To do this you just need to add
[ScriptIgnore(ApplyToOverrides = true)] into your text template (.tt) file.
Here a portion of my text template before
#>
<#=codeStringGenerator.NavigationProperty(navigationProperty)#>
<#
Once I inserted the code the line above the codeStringGenerator my classes auto generated and looked like this:
[ScriptIgnore(ApplyToOverrides = true)]
public virtual ICollection<Currency> Currencies { get; set; }
I also needed to modify the UsingDirectives function to insert "using System.Web.Script.Serialization;"
Related
I know that I can use virtual keyword to tell the entity framework that the child table should be loaded LAZY way. as,
public class Person
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
public virtual History PastHistory { get; set; }
public virtual ICollection<Blog> Blogs { get;set; }
}
public class Blog
{
..... blah.. blah.... blah
}
public class History
{
.... blah blah blah
}
Now, my question,
As History is not a collection but 1:1 mapping for another entity, should I mark History as Virtual if I want to load History Lazy way ?
Is there any benefit for marking the simple properties (i.e. Name: string, Age : int) as virtual ? At this moment, I marked all my simple properties as virtual for no obvious reason. If anyone confirms me that marking simple properties as virtual has no effect at all in EF Code First, I will remove the marks to look my POCO clearer.
Thanks.
If History is still related entity (record from another table) you must also mark it virtual to enable lazy loading. What is even more important if you want to use lazy loading for Blogs all other navigation properties in entity must be virtual as well.
Marking all simple properties virtual will allow EF to use dynamic change tracking.
Both lazy loading and change tracking is performed by dynamic proxy - a type created at runtime and derived from your entity type. Virtual keyword is necessary to allow this derived type to override (wrap) your property code into new code performing either lazy loading of navigation property or informing EF context about changes in simple property.
I am in midst of developing an application using Entity Framework code first 4.1 and MVC3. Here are three entities that I have, basically, State => City => Locality.
public class State {
public virtual List<City> Cities { get; set; }
}
public class City {
public virtual List<Locality> Localities { get; set; }
public virtual State State { get; set; }
}
public class Locality {
public virtual City City { get; set; }
}
It can be seen that I am using bi-directional relationship for all three entities. Json does not allow that, so I am somewhat frustrated. Basically, I need to navigate in either direction. For example given a City I want to be able to locate State to which it belongs easily.
I scanned the web and came across a couple of workarounds, but none of them suits my scenario. The first was to make the relationship unidirectional(who will do that !) and I don't want that. Other was to introduce ViewModel with only the properties that I need, but then that would mean duplicate code if I need to use all the fields of Entity regularly. Also my controller will be flooded with those properties. So I don't like that too.
I was thinking that this was just basic stuff, but now I am struggling to find a workable solution. If anyone has a better alternative(perhaps something in MVC3), please help me out.
You could try using JavaScriptSerializer directly and registering your own converter to control the serialization process.
I am not an ASP expert, but I think the solution might be similiar to what I woudl do in Java, Groovy or python or any other language.
The best solution I could propose is to make City.Localities a kind of "transient" (in Java terms) field - i.e. don't serialize it, but update it at loading time (when you build the structure). This can be encapsulated in setter for City of the Locality class.
So in Locality.setCity, in the set method you should call (city->localities.append(this) (whatever language you write it in). This way it will become a "runtime cache" of City->Localities which will be build once during loading.
The problem appears to be a native issue with the DataContractJsonSerializer support for Entity types. In short, Entities that have relationships (i.e. two-way) with other Entity types cannot be serialized through Json. In your example: a State table connected to a Cities table will not translate well into Json serializing because a State may have many cities and a City is associated with a State.
One quick solution would be anonymous object projection.
Something like this example:
public JsonResult Orders()
var results = from Ord in databaseContext.Orders
select new
{
OrderID = Ord.ID,
OrderTitle = Ord.Name,
OrderDate = Ord.OrderDate
}
return Json(results);
}
For reference, see this: Serializing Entity Framework Objects into JSON Using ASP.Net MVC
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 will use LINQ-to-SQL when the database is ready and use the entities there as models in my aplication. I'm trying to program against a interface to make changes to the program easier and I just realized that if I would later change from LINQ to something else I would have to create new model objects that would represent something very similar to the LINQ entities.
So I thought of creating interfaces for each entity and expose the properties and methods I would use in the program and aren't LINQ specific. But when I would apply this interface to the entity class would the implementation automatically bind to it's properties.
I'll give you an example to explain better.
I have table Cars that amongst others has the columns producer, type and wheels
So I make the interface ICar
public interface ICar
{
string Producer { get; set; }
string Type { get; set; }
int Wheels { get; set; }
}
The Car entity object will have these exact properties so will that work as the implementation of these properties or will they be defined seperatly so you get ICar.Producer and Car.Producer in the class?
This might be helpful: Linq to Sql, Programming Against an Interface and the Repository Pattern
First link is broken, check here instead: ORM and Repository pattern
I'm new to Windsor, but I'm certain there must be a way to do this...
I have a class with three different constructors:
public MyClass(string SomeParam)
{
...
}
public MyClass(string AnotherParam, string YetAnother)
{
...
}
public MyClass(string AnotherOne, string YeahIKnow, string AnnoyingExampleParam)
{
...
}
In my external configuration file, I have my service defined as:
<component
id="IMyClass"
service="IMyInterface, MyAssembly"
type="MyClass, MyOtherAssembly">
<parameters>
<AnotherOne>string value #1</AnotherOne>
<YeahIKnow>string value #2</YeahIKnow>
<AnnoyingExampleParam>string value #3</AnnoyingExampleParam>
</parameters>
</component>
When Windsor initializes an instance of my class, it only wants to initialize using the first (single string parameter) constuctor of my class, when I really want Windsor to use the third constructor.
I don't see anything in the docs about forcing the kernel to us a particular constructor using an external configuration, even though I can find references to doing it in code, but that sort of defeats the purpose of an external configuration!
Any advice would be appreciated.
Best,
David Montgomery
What version of Castle? I recall, from the depths of what goes for my memory at 4am in the morning, that there was a resolution for constructor work in Castle 2.0.
Humm, memory coming back a little now... Something tells me that Castle will construct the object with the first public ctor. May be as simple as moving what you want for Castle to load, to the top.
If that doesn't work for you, perhaps refactor your code a little?
Option 1) Make the first two constructors internal.
Option 2) Use a Factory pattern for your complex objects, which will utilize castle on the backend to new up the more simple or complex version.
Option 3) Create 3 classes from your base superclass, each having a more complicated constructor. This way, you can specific in the Castle config file exactly which service to load. For example:
public abstract class BaseClass
{
public BaseClass(String requiredParam)
{
...
}
}
public class SimpleClass : BaseClass
{
public SimpleClass(String requiredParam, String anotherParam)
: base(requiredParam)
{
...
}
}
public class MoreComplexClass : SimpleClass
{
public MoreComplexClass (String requiredParam, String anotherParam, String yetAnother)
: base(requiredParam, anotherParam)
{
...
}
}
But, I myself have not run into this yet. Mainly because I stick to only public 1 ctor on my classes, with a few private/internal ctors for things such as Linq to new up my objects with an empty ctor (since Linq doesn't support Dependency Injection, boo).
Note that in that last statement, internal ctors, that my SRP (Single Responsiblity Pattern) for resolving my IoC components is external, in a seperate higharchy assembly (i.e. an application or UI layer). Since it not internal to my domain objects, the internal ctors are not seen by Castle.
You must be doing something wrong.
Windsor uses the greediest constructor it can satisfy. If it uses the smaller one, you perhaps have some typo?
when your type is the service, you don't have to specify both
service="MyClass, MyAssembly"
type="MyClass">
remove the type.