So I got my mind around the models, if I change a field, I know how to modify the object properties to match. Ditto the relationships - add a hashset here and there to reference linked items.
But I read the ORM (the main model page) and that thing just mystifies me.
Like this:
So a PrefCategory has many Prefs. got it.
But it has a required PrefCategory??? It requires itself?
Anyhow, Applying the American credo just get it done, I came up with this:
To complete this tutorial you will need WinMerge.
First open up your relational mode in Models. Copy all the text.
Open WinMerge, hit the 2 pages icon to create a new comparison, and paste the code into the left pane.
Now in Visual Studio, create a new MVC project. in Solution Explorer, right click Models - Add - Ado.Net Entity Model.
Choose your development database, and tick all the same tables and views you are using in your main app.
It will create all the table models.
Now open the same relational model, copy all and paste it into the right pane of WinMerge. Hit Refresh.
Now you'll see everywhere that your code differs from what you'd see if you imported the model fresh.
In my case, I could easily see where I had an old .WithOptional that had now become a .WithRequired. I modified my project relational model and suddenly I was no longer getting the
Multiplicity conflicts with the referential constraint in Role 'blah blah thing that doesn't exist by that name anywhere in the project' in relationship 'blah blah'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'.
You have a page with something embedded, a partial view, a generated image, or something. And it's odd, but the first time you load the page, everything works, but every time you reload (like someone clicks a button on the page), MVC claims it can't find the action.
InnerException:
ErrorCode=-2147467259
HResult=-2147467259
Message=A public action method ... was not found on controller '...Controller'.
Source=System.Web.Mvc
WebEventCode=0
You check and the action is right there!. In my case it looked like this.
//Get: ProductPartial Blocks
[HttpGet]
[AllowAnonymous]
public ActionResult ProductBlockPartial(int? ID)
{
if (ID.HasValue)
{
Product model = db.Products.Find(ID);
return PartialView(model);
}
else
{ return null; }
}
The answer, my friend, is that pesky [HttpGet]. That tells the action to only respond to get requests, and when you pushed the button to post data back to the page, it became a post. And the post flows down from the main page to the partial view as well.
Just remove the [HttpGet] from the action and you're good as gold!
...
Bryan Valencia is a contributing editor and founder of Visual Studio Journey. He owns and operates Software Services, a web design and hosting company in Manteca, California.
The only problem is that when I get to my Save(), I get this:
Attaching an entity of type [MODEL] failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Apparently, Entity Framework thought that my oldAssignment was blocking the assignment object from the postback. The solution is simple: change this:
Today I needed to split a list of companies into Companies and Relocation Companies. The data is in the same table and model, but presentation rules for this project require 2 lists.
SO:
Taking a single dataset from the controller:
// GET: Companies
publicActionResult Index()
{
return View(db.Companies.ToList());
}
I took this bit of view/index code from the auto-generated “Code First From Database” tool…
@Html.ActionLink("Edit", "Edit", new { id = item.UniqueId }) |
@Html.ActionLink("Details", "Details", new { id = item.UniqueId })
</td>
</tr>
}
</table>
And I made 2 copies (in my case I will only ever need 2 lists). I changed the highlighted line in the above to…
@foreach (var item in Model.Where(d => d.isReloCompany == false).OrderBy(d=>d.CompanyName))
Note that I can add LINQ into the view easily and I did not have to split my list beforehand in the controller. The second copy of this line has .isReloCompany==true.