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.
Related
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.
I am creating some view models for my ASP MVC web app.
I created "code first" models for database. Is it a good way to derive view models from database models?
Example database model:
public class Project
{
[Key]
public int Id { get; set; }
public int? CustomerId { get; set; }
public int TypeId { get; set; }
public string Number { get; set; }
public string Name { get; set; }
}
View model:
public class ViewModelProject : Project
{
[NotMapped]
public DateTime? Start { get; set; }
[NotMapped]
public DateTime? End { get; set; }
[NotMapped]
public string Manager { get; set; }
}
Is this the right way or is it completely false?
EDIT (subquestion):
I have some very simple database models like ProjectType, which only contains i.e. two properties. Should I also fragment those models in model view or can I make it that way:
Simple database model:
public class ProjectType
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int? Code { get; set; }
}
Can I use it like so:
public class ProjectVM
{
public string Name { get; set; }
public int Number { get; set; }
public ProjectType Type { get; set; }
}
Or does it have to be fragmented like so:
public class ProjectVM
{
public string Name { get; set; }
public int Number { get; set; }
public string Type { get; set; }
public int TypeCode { get; set; }
}
I would not recommend doing it this way. I (and many others) have tried it and it doesn't work well. You will inadvertedly run into troubles, since an MVC model has to be tailored to the view and what you get from the DB rarely fits. Sure, you can hammer it into place, but the code quickly gets messy and store-related and UI code starts to mangle together. This even shows in your example, since you have to put the NotMappedAttribute (which is related to data storage), to ViewModelProject (a class at UI level).
There are many other examples to show this problem, but an especially good one I find when you want to serialize a model object to JSON and send it to a JavaScript client. The JSON serializer takes the values of all public properties and adds them to the JSON. If you want to exclude a property, you have to mark it with a ScriptIgnoreAttribute, which you would also have to apply to the base class, which breaks separation between UI and store-related code.
The better way to go is to keep the staorage model and the MVC model separated and to map the data from one to the other (there are already pre-existing frameworks that help you with that, such as Automapper). This comes with additional advantages, for example better testability, since you are now not dependent on a specific data store to create model instances.
I am willing to create a view that matches with the model below.Imagine my model is as follows.(I removed remaining code for brevity)
public class ProposalData : DefaultEntity
{
[Key]
public int Id { get; set; }
[Required]
public virtual DebtorData Debtor { get; set; }
public virtual ICollection<CreditorData> Creditor { get; set; }
public virtual ICollection<WarranterData> Warranter { get; set; }
I tried to create a view using sql management but because Debtor,Creditor,Warranter all have id column,it throwed the below error.
I know what caused this error but I haven't found a solution yet.Isn't it possible to create a view that matches with complex object/entity without changing my model or adding any data annotation ?
I have a couple of classes:
public class MyGoalsModel
{
[Key]
public string Name { get; set; }
/*Some local bools*/
public List<MyGoalString> myGoals { get; set; }
}
public class MyGoalString
{
public int MyGoalStringID { get; set; }
public string GoalString { get; set; }
public bool Selected { get; set; }
}
I can populate them correctly, and the code (EF?) generates the necessary hidden foreign keys to link them (all ok in SQL) and recover the information for MyGoalsModel, but the List is always null.
I use the following to get the entry I want:
MyGoalsModel goals = db.MyGoals.Find(Name);
but when I investigate the code goals.MyGoals is always null.
Am I missing something, is there a better way to recover the information with the lists present?
Add the keyword virtual so EF can create a proxy for your List and lazy load the data when needed.
Edit: Or as stated in the accepted answer in this question.
Ok, I have 3 models. WorkoutViewModel has a one to many relationship with WorkoutExerciseViewModel. WorkoutExerciseViewModel has a one to many relationship with ExerciseSetViewModel. I need a dynamic “Create View”, that will allow me dynamically add Exercises to Workouts, and Sets to Exercises. I then want to save a Workout including all exercise and set records back to the database. I just need to validate that there is at least 1 exercise for the workout created and at least 1 set for the exercise created. Ultimately I just need to push a Workout View Model back to the controller with all of the populated nested IEnumberable objects present. Can anyone point me in the right direction?
public class WorkoutViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtal IEnumerable<WorkoutExerciseViewModel> WorkoutExercises { get; set;}
}
public class WorkoutExerciseViewModel
{
public int Id { get; set; }
public int WorkoutId { get; set; }
public int ExerciseId { get; set; }
public virtual ExerciseViewModel Exercise { get; set; }
public virtual IEnumerable<ExerciseSetViewModel> ExerciseSets { get; set; }
public string ExerciseFullname
{
get
{
return Exercise.Equipment.Name + " " + Exercise.Name;
}
}
}
public class ExerciseSetViewModel
{
public int Id { get; set; }
public int WorkoutExerciseId { get; set; }
public int Set { get; set; }
public int Reps { get; set; }
public int Weight { get; set; }
public string WeightValueType { get; set; }
}
There's really more to this than can reasonably be discussed in a StackOverflow answer, but I'll give you enough to start with.
As far as adding new exercises and sets within those exercises go, that's just JavaScript. You'll need to have some button that the user can click to add a new one, and tie the click event on that button to a handler that will add the appropriate HTML (form fields and such) to the page. There's many different ways to go about doing that, some more difficult than others. Most likely you want to look into some JavaScript templating library or a more full stack JS library like Knockout to make things easier. The only other thing to keep in mind is the conventions the modelbinder uses to wire everything from the post body to an instance of your model. For collections, it expects fields to have name attributes in the form of CollectionPropertyName[N].PropertyBeingEdited, where N is the position within the collection. So, the name attribute for ExerciseFullName for the first exercise would be WorkoutExercises[0].ExerciseFullName.
Your post action would simply take your same main view model:
[HttpPost]
public ActionResult Create(WorkoutViewModel model)
{
...
}
As long as you follow the property naming conventions for all the fields in your form, the modelbinder will happily wire everything from the post body onto your WorkoutViewModel instance.