Is it possible to set "UpdateCheck" to "LastUpdatedOn" field of parent object while updating children?
I am very confused by this question. The ColumnAttribute UpdateCheck can only be set to one of the following : Never, WhenChanged, Always.
If you are trying to timestamp a parent object when a property in a child object is changed, you can use partial methods to capture the change event and run other statements there.
public partial class MyObject
{
partial void OnMyPropertyChanging(string value)
{
// fire set other linq against parent here
}
}
Related
I am trying to use the caliburn.micro Conductor. According to the docs, a Conductor doesn't necessarily need to be of type Screen, it can actually be any POCO.
So I create my class like this:
public class StoreContentsViewModel : Conductor<MyItem>.Collection.OneActive
{
protected override void OnInitialize()
{
...
foreach (MyItem item in Collection)
{
Items.Add(item);
}
ActivateItem(Items[0]);
}
}
but I get a binding error
System.Windows.Data Error: BindingExpression path error: 'Items' property not
found on 'MyItem' (HashCode=107597610). BindingExpression: Path='Items'
DataItem='MyItem' HashCode=107597610); target element is
Microsoft.Phone.Controls.Pivot' (Name='Items'); target property is
ItemsSource' (type 'System.Collections.IEnumerable')..
I thought that it was Conductor the class that implements Items list, but caliburn is trying to bind MyItem. Why is that?
I want to have a Pivot, which receives a list of MyItem in the bindable property Items, and displays them according to an ItemTemplate I defined. Do I need a ViewModel for this??
I've read the documentation several times but I am still lost, could you please explain me what's happening?
Found the problem!
I was setting a DataContext in the Grid that contains the Pivot, overwriting the convention DataContext which is the ViewModel. I deleted that and worked perfect.
So, it is true that you can use any POCO in a Conductor.
Please can you help me with the problem below:
I have 2 domain classes(Parent, Child) which I do not want to be mapped to a table, so I put mapWith=none. However, when I do parent.validate() I want the validation to be cascaded to the child. How can I enable cascade validation for domain objects which are not mapped to a table?
Many thanks in advance!
Don't know if you can by design.
You could optionally add a customValidation() method on the parent object to initiate a check which is looping over the children and invoking their validate() methods. Any errors on the children could then be added to the errors object of the parent object.
boolean cascadedValidation() {
this.validate();
children.each {
if (!it.validate()) {
it.errors.allErrors.each { err ->
// Bind somewhere on parent object
}
}
}
return this.hasErrors();
}
I have a view model sent to the edit action of my controller. The ViewModel contains references to EntityObjects. (yea i'm fine with it and don't need to want to duplicate all the entities properties in the viewmodel).
I instantiate the view model and then call UpdateModel. I get an error that a property is "null" which is fine since it is a related model. I am trying to exclude the property from being bound during model binding. On debugging it I see in the entity where the model binder is trying to set the value of the property to null.
Here is my edit action:
var model = new SimplifiedCompanyViewModel(id);
var excludeProperties = new string[] {
"Entity.RetainedEarningsAccount.AccountNo"
,"Property.DiscountEarnedAccount.ExpenseCodeValue"
,"Entity.EntityAlternate.EntityID"
,"Property.BankAccount.BankAccountID"
,"Entity.PLSummaryAccount.AccountNo"
,"Property.RefundBank.BankAccountID"
,"Company.Transmitter.TCC"
};
try
{
UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);
if (ModelState.IsValid)
{
//db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(model);
}
I have looked at a few other issues about specifying a "prefix" but I don't think that is the issue since I am telling it to bind to the viewmodel instance not just the entity object.
Am I excluding the properties correctly? Strange thing is is only seems to happen on this item. I suspect it may be an issue with the fact that there is actually no refund bank related to my entity. But I have other related items that don't exist and don't see the same issue.
More info... since I'm told me model isn't designed well.
The Company is related to a BankAccount. The Company view shows the currently related BankAccount.BankAccountId and there is a hidden field with the BankAccount.Key. I use jQueryUI autocomplete feature to provide a dropdown of bank account displaying the BankAccount.BankAccountId and when one is selected the jQuery code changes the hidden field to have the correct Key value. So, when this is posted I don't want the current bankaccounts BankAccountID modified, hence I want it to skip binding that field.
If I exclude BankAccountId in the model then on the BankAccount edit view the user would never be able to change the BankAccountId since it won't be bound. I'm not sure how this indicates a poor model design.
Use the Exclude property of the Bind attribute:
[Bind(Exclude="Id,SomeOtherProperty")]
public class SimplifiedCompanyViewModel
{
public int Id { get; set; }
// ...
}
This is part of the System.Web.Mvc namespace. It takes a comma-separated list of property names to exclude when binding.
Also you should consider using TryUpdateModel instead of UpdateModel. You can also just have the default model binder figure it out by passing it as an argument to the constructor:
public ActionResult Create([Bind(Exclude="Id")]SimplifiedCompanyViewModel model)
{
// ...
}
A very simple solution that I figured out.
try
{
UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);
ModelState.Remove("Entity.RetainedEarningsAccount.AccountNo");
ModelState.Remove("Property.DiscountEarnedAccount.ExpenseCodeValue");
ModelState.Remove("Entity.EntityAlternate.EntityID");
ModelState.Remove("Property.BankAccount.BankAccountID");
ModelState.Remove("Entity.PLSummaryAccount.AccountNo");
ModelState.Remove("Property.RefundBank.BankAccountID");
ModelState.Remove("ompany.Transmitter.TCC");
if (ModelState.IsValid)
{
//db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(model);
}
Another option here is simply don't include this attribute in your view and it won't be bound. Yes - you are still open to model injection then if someone creates it on the page but it is another alternative. The default templates in MVC will create your EditorFor, etc as separate items so you can just remove them. This prevents you from using a single line view editor with EditorForModel, but the templates don't generate it that way for you anyways.
EDIT (adding above comment)
DRY generally applies to logic, not to view models. One view = one view model. Use automapper to easily map between them. Jimmy Bogard has a great attribute for this that makes it almost automatic - ie you create the view model, load up your Customer entity for example, and return it in the action method. The AutpMap attribute will then convert it to a ViewModel. See lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models
Try the Exclude attribute.
I admit that I haven't ever used it.
[Exclude]
public Entity Name {get; set;}
I am confused with this:
I have an action ,say Parent ,and in the corresponding view file ,I have called a child action ,say Child ,both Parent and Child actions are in the same controller.
and I need the Child action and the Parent action to share some data in the ViewBag.Now ,what I should do ?Here is my question:
when I call the Child action in parent's view file ,I pass the viewbag to it like this:
#Html.Action(ViewBag).
in my child action ,I do this:
public PartialViewResult Child(Object ViewBag)
{
//using the data in ViewBag
}
Is this the right way ? Does the viewbag object passed by reference or it is a different object then the original viewbag(more memory needed)?
Or if the Child action is sharing the viewbag with its calling parent Action by default?
From Darin Dimitrov's answer ,I knew that I can't do something like this:#Html.Action(ViewBag)
But I really need to pass the child action muti-parameters,what can I do ?
Child actions follow a different controller/model/view lifecycle than parent actions. As a result they do not share ViewData/ViewBag. If you want to pass parameters to a child action from the parent you could do this:
#Html.Action("Child", new { message = ViewBag.Message })
and in the child action:
public ActionResult Child(string message)
{
...
}
There is a way, but you have to create a custom abstract class as the base class for your razor views. Then expose whatever you need to from parent to child actions.
This is how I get the root controller's ViewBag inside a class inheriting from WebViewPage
private dynamic GetPageViewBag()
{
if (Html == null || Html.ViewContext == null) //this means that the page is root or parial view
{
return ViewBag;
}
ControllerBase controller = Html.ViewContext.Controller;
while (controller.ControllerContext.IsChildAction) //traverse hierachy to get root controller
{
controller = controller.ControllerContext.ParentActionViewContext.Controller;
}
return controller.ViewBag;
}
I am trying to extend my Linq-to-Sql entity with a few extra properties. These are "calculated" properties based on data from the underlying SQL View. For example, think of having a Date of Birth field, which is used to calculate an extended Age field.
I tried to extend my entity class by extending the OnLoaded() method.
I get a compile time error however stating that I cannot create it. I checked the designer code for my LTS entity class, and it doesn't have a partial definition for any of the expected extension points.
I checked a few of my other LTS entity classes and they do have these extension points. The only difference I see is that the one without is loaded from a SQL View, rather than a table. Is there a way to hook into a "Loaded" event when loading from a SQL View?
TIA!
I found that I did not have a PrimaryKey specified for my Linq-to-Sql entity class. I believe without a Primary Key specified, no extension methods generated in the entity class. Once I specified a Primary Key on my LTS entity class definition (through the designer), I was able to extend the OnLoaded() event.
You can do this by means of a property. Just create a partial class with the same name as your entity. Any properties or methods that you add will automatically be part of the entity and allow to use any of its members.
Here's an example of the pattern:
public partial class [The Name of the Entity]
{
public int Age
{
get
{
return CalculateAge(this.DateOfBirth);
}
}
}
Here's some logic on how to calculate the Age (Source: Geekpedia)
public static int CalculateAge(DateTime BirthDate)
{
int YearsPassed = DateTime.Now.Year - BirthDate.Year;
// Are we before the birth date this year? If so subtract one year from the mix
if (DateTime.Now.Month < BirthDate.Month ||
(DateTime.Now.Month == BirthDate.Month && DateTime.Now.Day < BirthDate.Day))
{
YearsPassed--;
}
return YearsPassed;
}