Setting an child property to null - c#

I am currently creating an application for migrating data, The data can be very complex as it can contain itself e.g
--Boss
--Supervisor
---Manager
---Supervisor
---Boss
----Employee
The application then shows the data as a checkbox where a use can select what data they want, the issue now is that behind the scenes I load the data and want to keep a separate list of the original source where i get the data from.
The issue is, if i wanted to decrease the size of the Boss object(the top level one, would setting null on the supervisor object decrease its memory size, or would it just create an orphaned element in memory and just increase my application memory use?
NB. The Elements the in hierarchy all come from the same base type and are in the format of List ..of Lists...Of lists ..,etc with other properties attached to them that might be of the same base type that cannot be shown on the hierarchy.
This is an example of the code i am using
public class AttributeConversion : BaseConversion
{
public AttributeConversion(string displayName)
: base(displayName)
{
//set up value
}
public AttributeConversion()
{
//default constructor for the serializer class
}
[XmlIgnore]
[Identity]
public int AttributeID { get; set; }
public string Name { get; set; }
//[XmlIgnore]
public int DataTypeID { get; set; }
[ControlAttribute]
[XmlArray("AttributeLookupSets")]
[XmlArrayItem("AttributeLookupSet")]
public List<AttributeLookupSetConversion> AttributeLookupSetConversions { get; set; }
public AttributeLookupSourceConversion AttributeLookupSource { get; set; }
[XmlElement("AttributeSetAttribute")]
public AttributeSetAttributeConversion AttributeSetAttributeConversion { get; set; }
[XmlElement("AttributeInteger")]
public AttributeIntegerConversion AttributeIntegerConversion { get; set; }
[XmlElement("AttributeFloat")]
public AttributeFloatConversion AttributeFloatConversion { get; set; }
[XmlElement("AttributeText")]
public AttributeTextConversion AttributeTextConversion { get; set; }
[XmlElement("AttributeDate")]
public AttributeDateConversion AttributeDateConversion { get; set; }
So in this particular instance, I would like to nullify all the objects with either XmlElement or XmlArray attributes. The goal is to flatten that hierarchy and then set all items to null, that way I can use the list for reference as to what Items I have at anytime in the hierarchy of objects, But I am unsure of the memory usage, so I wanted to at least ensure i shed any memory i might be wasting.

Related

Is there a way to conditionally serialize C# list objects based on a property?

I have an MVC Model that generates JSON files, based off of user inputs, that are used as part of an automated workflow. The issue that I am having is figuring out how to change the order in which a list of objects are serialized based off of a specific property value.
Here is a simplified look at my model:
public class Ticket
{
public string TicketNumber { get; set; }
public string TicketName { get; set; }
public string ApplicationName { get; set; }
public IList<Jams> JamsList { get; set; }
}
public class RootObject
{
public Ticket ChangeTicket { get; set; }
}
public class JamsDestination
{
public string Dev { get; set; }
public string QA { get; set; }
public string Prod { get; set; }
}
public class Jams
{
public string TFSLocation { get; set; }
public string FileName { get; set; }
public string JamsType { get; set; }
public JamsDestination JamsLocation { get; set; }
}
(I am using Newtonsoft.Json and the SerializeObject() function in the post section of my controller)
JamsType is a drop down list populated from a sql table (Variable, Job, Trigger, and Box). What I am trying to do is ensure that any Jams change (in the list: JamsList) is serialized in an order that ensures that all Jams changes of JamsType = Box are serialized last, in order to ensure that it will run properly as a part of our automated workflow. Is there any way to accomplish this without setting up some form of Javascript function in the view to reorder them before they are indexed? (My view is a dynamic table setup so it is not guaranteed that there even will be any Jams changes each time, let alone how many are associated with a ticket).
I realized that I just needed to add Linq logic into my controller PRIOR to serializing the JSON file by doing the following:
ticket.JamsList = ticket.JamsList.OrderBy(jams => jams.JamsType == "Box").ToList();
All this actually does is just reorder the list of Jams changes to meet my conditions before it gets serialized, rather than changing the order it serializes the list (how I thought it needed to be performed).

Object List in kendo-grid mvc

I have a kendo-grid with a certain number of fields which derive from my model, recently I added a List<Entity> to this model. However when I try to load my grid while the list is not null it just fails to load anything at all. I know that this happens because a nested object isn't supported by the kendo-grid by default. I haven't added anything for this List in my view yet and I'm wondering how to accomplish this.
There's one error message I get while loading the data which is:
System.InvalidOperationException: A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.BinLocation_Item_5FB823DBD32445977E0B51123416DFB49CA7B0CAA42A233C8DB7B8E94493BEEE'.
Model:
public class ViewModel
{
[Required]
public int ID { get; set; }
[Required]
public int LineNum { get; set; }
public string ArticleName { get; set; }
[Required]
public string ArticleID { get; set; }
public List<Location_Item> locations { get; set; }
}
Like Curiousdev said set "db.Configuration.ProxyCreationEnabled = false;" did the trick for loading the data. Getting the list data in the grid didn't quite work however and will be displayed in some other way.

Filling list with different types of objects

I'm working on a recommendation algorithm which all works fine. But now I wanted to implement this code into the branch of my development team.
I'll start from the top. My algorithm can recommend 2 types of objects, restaurants and dishes.
Restaurant:
public class Restaurant
{
public Guid Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public List<Tag> Tags { get; set; } = new List<Tag>();
public int PriceRange { get; set; }
}
And dish:
public class Dish
{
public Guid Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public virtual Restaurant rest { get; set; }
[ForeignKey("rest")]
public Guid RestaurantId { get; set; }
public List<Tag> Tags { get; set; }
}
Now my product owner wants the list to be like this when it's being presented on the home page of our app:
[Restaurant][Dish][Restaurant][Dish] Etc...
So basically, he wants to alternate the type of object that's being recommended. These dishes and restaurants are completely separate. They are generated by my algorithm purely on the user's preferences and have no correlation with eachother at all.
Now my problem is how to return such a list. I figured I'd need a wrapper class which contains either a Restaurant or Dish like this:
public class RecommenderItem
{
public Restaurant rest { get; set; }
public Dish dish { get; set; }
}
This way I can create a List<RecommenderItem> and return that to the client. The client would only need to check which attribute is null and retrieve the values from the one that is not.
I'm just unsure if this is the correct approach. Are there any 'best practices' in doing this? Let me know if I should elaborate more!
If they doesn't have common base class then creating one wrapper class is the best solution. At the same time you can be more flexible and create something like
public class RecommendationItem
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PageUrl { get; set; }
public object Entity { get; set; }
}
So you can include all common information in this class and client will not be required to check with which object type he works. In such case it would be easier to add one more item type. At the same type I added reference to entity itself - it can be used if some specific handling for one or two item types is required.
You can declare an interface IRecommenderItem:
public interface IRecommenderItem
{
//shared properties
}
public class Restaurant : IRecommenderItem
{
}
public class Dish : IRecommenderItem
{
}
than, you can type:
List<IRecommenderItem> m = new List<IRecommenderItem>();
If you are going to connect pairs of elements it always makes sense to me to... well, pair the elements. I am assuming that each dish is specific to a particular restaurant? So the list would be [Restaurant1][Dish for Restaurant1][Restaurant2][Dish for Restaurant2]...?
I like the previous answer by oryol creating a common base class as well.
So, your RecommenderItem class is fine. But fill in both properties and pass a list of pairs back. Expand the list into the full set of items for display by creating a new List, iterating through the list of RecommenderItems and adding Restaurant and Dish from each entry in it.

Default values only for unset properties when deserializing

I have a little problem, which I'm guessing should have been solved with better code design from the beginning. But here I am.
I have an app with a pretty large user base. The app uses profiles. The profiles are are deserialized from file when starting the app.
In new releases the profile class sometimes gets new properties. If the profile is deserialized from an older version these properties will be uninitialized. Where as they will have some set default values if the profile is created with the current version of the app.
Is there a simple way of initializing a property with a default value if the serialized version doesn't have it?
You can specify a method to run after deserializing where you could set default values:
using System.Runtime.Serialization;
[Serializable]
class Car
{
public int Id { get; set; }
public string Make { get; set; }
public int Doors { get; set; }
public string Foo { get; set; } // added property
...
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
if (string.IsNullOrEmpty(this.Foo))
this.Foo = "Ziggy";
}
}
You might want to consider ProtoBuf-NET which is a data contract binary serializer. It is much more flexible about these things, more options, faster and creates smaller output. I just double checked to be sure, and ProtoBuf will not undo fields it doesnt have information for. So:
[ProtoContract]
class Car
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Make { get; set; }
[ProtoMember(3)]
public int Doors { get; set; }
[ProtoMember(4)]
public string Foo { get; set; } // new prop
public Car()
{
this.Foo = "Ziggy";
}
...
}
If there is no serialized value for Foo, the old value from the ctor is retained. So you could initialize new properties there and not have to worry about them getting reset to null. If you have a lot of properties like Bitmap, Font and Rectangle you might want to stay with the BinaryFormatter.

N2 CMS: Are nested collections of ContentItems possible?

Can an arbitrary number of ContentItems of the same class to be added to a page in N2? And can they be nested?
I.e. Is there a way to define a collection of ContentItems as a property in N2? I’d also like to nest these if possible so we can run more meaningful queries against the data. (I.e. instead of using huge EditableTextRegions which will be difficult to query.)
I currently have the following model as an ‘ideal’, can this be N2ified? (I’ve left off attributes and N2 style getters/setters for clarity)
public class Link : ContentItem
{
public string Text { get; set; }
public string Title { get; set; }
public string Url { get; set; }
}
public class Panel : ContentItem
{
public string Title { get; set; }
public string Text { get; set; }
public List<Link> Links { get; set; } // Should show an expandable number of “Link” editors in the CMS editor
public string ImageUrl { get; set; }
}
public class Page : ContentItem
{
public string Title { get; set; }
public string BodyText { get; set; }
public List<Panel> Panels { get; set; } // Should show an expandable number of “Panel” editors in the CMS editor
}
Yes - instead of Get/SetDetail in your properties use Get/SetDetailCollection.
FYI if you're using 2.1 you can just make your properties virtual and leave off the Get/SetDetail - not sure if this works for the DetailCollection methods though, but you can mix the two.
I'd be careful with what you're proposing though - nesting collections like this is likely to cause you SELECT N+1 issues down the line. If you can't change the design then I'd recommend turning on N2's database caching (which is just NHibernate's 2nd level cache), this way as much as possible will be kept in memory without hitting the database too much.

Categories