I have a many-to-many relationship between Foo and Bar
Here's a simplified Foo
public class Foo
{
public virtual ICollection<Bar> Bars {get;set;}
}
and I want to save a new foo with some bars attached:
var foo = new Foo();
foo.Bars.Add(bar1); //I'll get an error that if Bars is not initialized
repo.Insert(foo);
repo.SaveChanges();
should I initialize the Bars in the constructor, is this how it should be done ?
(using EF4 CTP5 codefirst)
I'd indeed initialize the collection in the constructor (if the collection is virtually always needed), or would change the getter to initialize whenever the collection is first needed (if the collection is not always needed).
Related
I'm trying to put two partialviews together but I keep getting errors.
I've got a Subject-model and a Category-model, and I've made partial views which seem to work perfectly, but when I put them together in a single view this pops up:
Error 1 'Myproject.Models.Subject' is a 'type', which is not valid in the given context
this is the only code in my view:
#{Html.RenderPartial("_CategoryPartial", Myproject.Models.Category);}
#{Html.RenderPartial("_SubjectPartial", Myproject.Models.Subject);}
I guess I will have to create a seperate viewmodel if all else fails, but I thought on checking on here first
The problem is that you are passing in the type of Model rather than an object.
void HtmlHelper.RenderPartial(string partialViewName, object model)
You could do this if you changed your code to;
#{Html.RenderPartial("_CategoryPartial", new Myproject.Models.Category());}
#{Html.RenderPartial("_SubjectPartial", new Myproject.Models.Subject());}
Then you would need to populate the properties within each object.
An alternative is to change your code to call a class which returns the populated objects, e.g.
#{Html.RenderPartial("_CategoryPartial", Myproject.Models.CategoryRepository.GetCategory(id));}
#{Html.RenderPartial("_SubjectPartial", Myproject.Models.SubjectRepository.Get(id));}
You need to be passing instances of those models to the partials, whereas you are just specifying the types, hence the error.
So yes, for this view, I would create a view model, something like:
public class ExampleViewModel
{
public Category Category {get;set;}
public Subject Subject {get;set;}
}
and then do:
#{Html.RenderPartial("_CategoryPartial", Model.Category);}
#{Html.RenderPartial("_SubjectPartial", Model.Subject);}
I created a Custom Control for monodroid. Following the tutorial N-20 CustomControl and this MvxListView because my control binding a IEnumerable.
My control inherits to FrameLayout, then I don't have access to Adapter property from Parent Class.
When I assign the List binding property and call the RaisePropertyChanged event. Doesn't raise up. How can I do that?
Thanks in advance.
Edit to show code
Talk is cheap, I Show the code.
This is the header of custom control and the list of binding.
public class DrawingBoardControl : View
{
private DrawingItems m_drawingItems;
[MvxSetToNullAfterBinding]
public DrawingItems CanvasItems
{
get
{
return m_drawingItems;
}
set
{
m_drawingItems = value;
this.Update();
}
}
...
I use a class called "DrawingItems", there are
public class DrawingItems : IEnumerable<IDrawingElement>
{
private List<IDrawingElement> myDrawingItems = new List<IDrawingElement>();
public IEnumerator<IDrawingElement> GetEnumerator()
{
return myDrawingItems.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public void Add(IDrawingElement element)
{
myDrawingItems.Add(element);
}
}
However, in other custom controls I use a IEnumerable and generic List and the problem persist.
When, I use RaisePropertyChanged in my ViewModel, the Items property don't raise.
Sorry for not include more information yesterday
There are always some answers for uncomplete questions:
If you cannot access the Adapter of the parent, the parent has to set the context of the child. There are no more options. Make your custom control fully bindable by exposing the complete interfaces. The list has to provide the context for the list items.
Somehow a customcontrol binding to a IEnumerable feels very wrong. A custom control for displaying a list item, I can understand, but not for a list. But of course it can be done. But you end up setting references to the container class en setting the datacontext or viewmodel of each item.
But please provide more info if you want others to help.
UPDATE:
Then I also update :) This provides some clues of the problem:
Don't assign a new list, but inherit the this from ObservableCollection, or manually call the raiseProperty with the correct parameters in the setter. I think it is by design assigning a new list will not call PropertyRaised.
As the 'App is King'-rule: in this case I notify the propertychanged myself. It might have something to do with the weak references problem (see the attribute on the ListItem property).
I have a viewmodel consisting of a handful of properties:
public class FooDataViewModel : IValidatableObject
{
/* Several Properties working as expected */
public ICollection<Foo> Foos {get; set;}
/* Validation working as expected */
}
Foo holds a few fields and works as expected:
public class Foo
{
/* Only a few basic properties, works as expected */
}
But I have some objects that are Foobar:
public class FooBar : Foo, IValidatableObject
{
/* Just a few more properties and some conditional validation */
}
I created a custom editor template for both Foo and FooBar. For my edit view, I simply use '#Html.EditorFor(m => m.Foos)' and editors for both Foo and FooBar are displayed. But when I submit to my HttpPost method, only Foo objects are created, and the FooBar specific data is lost. How can I make sure that that the FooBar objects are created?
How can I make sure that that the FooBar objects are created?
You will need to include this information in the request and write a custom model binder that is able to use this information and instantiate the proper type. I have illustrated the concept here: ViewModel with List<BaseClass> and editor templates
I have a View which can be accessed when the Model is populated with data and when the Model is completely empty.
When the Model is empty, it means that the user clicked on "Create New".
At the moment, I am getting a NullReferenceException because there obviously isn't anything inside Model. If I pass an object over to the view then the browser just freezes because the object contains null items inside it.
Is there a quicker/better way of doing this instead of doing:
MyObject myObj = new MyObj();
myObj.InnerObj = new Object(){data = ....};
...
I hope that makes sense :)
You can use the NullObject pattern:
Create a subclass of MyObject that has all properties prepopulated and methods that purposefully implement no behavior. For instance:
public sealed class NullObject : MyObject
{
public object InnerObj { get; private set; }
public NullObject()
{
InnerObj = new Object { ... };
}
}
It may not be the most clever way to deal with it, but I will sometimes wrap the Model-dependent code in the view in
#if(Model.Property != null)
So if you're having a single view for 'Create' and 'Edit', with the difference being the population of properties in the model, test those properties with an 'if', then code accordingly.
A better solution (I think) that we eventually implemented is an enum that we call "EditState" with two values: 'create' and 'edit'. Make the EditState a property in the viewModel. Set or check it's value and render the view accordingly (either with inputs for create, or displays or however you're setting it up.) It's a nice and easy to read way to differentiate between the create flow and the edit flow.
I have a simple database from which I am generating Linq2SQL classes using a datacontext. In one part of my application I would like to load the entire relationship such that I get child records. In another part of the application I am passing that relation across the boundary between model and view and I would like to not pass the entire thing since the set of children is pretty large. Is there a way to not have these child classes exported in one section and be exported in another?
I am aware of setting the child property to False in the datacontext but that is a global change.
You can do it with the DataLoadOptions setting on the data context. You'll probably have some sort of builder class somewhere in your application. For the quickest and dirtiest solution, you could do something like the following...
public class SqlContextBuilder
{
public SqlContextBuilder(MyDataContext dataContext)
{
_dataContext = dataContext;
}
private readonly MyDataContext _dataContext;
public MyDataContext CreateEagerLoadingContext()
{
var options = new DataLoadOptions();
// set those options!
_dataContext.LoadOptions = options;
return _dataContext;
}
public MyDataContext CreateLazyLoadingContext()
{
// lazy loading happens by default
return _dataContext;
}
}
One of the solutions is to pass the relation as IQuerable. This will make sure that the relation is not executed until is it required. If you loop over the relation then it will be executed for each child.
Another technique might be to use DTO objects to create a ViewModel of which you like to pass. This means your ViewModel might be very similar to the interface.