Petapoco missing attributes IgnoreOnInsert, IgnoreOnUpdate - umbraco7

I'm trying to use Petapoco in my Umbraco powered website. On my poco's I have a column called Created which has a default sql value (getDate()). I would like that column to be ignored on insert and update by Petapoco, but not on read.
Any idea how can I achieve that elegantly? perhaps with a custom mapper or including some new attributes in Petapoco engine (like IgnoreOnInsert, IgnoreOnUpdate).
I've been using some hacks, one of them was having two poco's for each table, one for insert-update and one for reading. But it's difficult to accept that as satisfactory.

I usually just make a class constructor and set the date property there. Something like
public class WhatEvs
{
...
public WhatEvs()
{
DateCreated = DateTime.Now;
}
}

In case anyone is still interested in this, I eventually found a nice solution.
And that is to stop using Petapoco and switch to NPoco, which has a nice attribute called 'ComputedColumn'.
If you decorate a property with [ComputedColumn] attribute, that property will not be used when NPoco generates insert and update queries, but it will be used in select queries.
That allows me to nicely have database handled values like CreatedDate or UniqueGuid which I don't touch, but am able to get when querying.
Thanks to Aaron who kindly answered this problem here:
https://github.com/CollaboratingPlatypus/PetaPoco/issues/421#issuecomment-348390149

Related

'Existing Entity' constraint

I'm reading some data from an excel file, and hydrating it into an object of class A. Now I have to make sure that one of the fields of the data corresponds to the Id of a specific Entity. i.e:
class A{
protected $entityId;
}
I have to make sure that $entityId is an existing id of a specific entity (let's call it Foo). Now this can be achieved using the choice constraint, by supplying the choices option as all of the existing ids of Foo. However this will obviously cause a performance overhead. Is there a standard/better way to do this?
I'm a bit confused about what you are doing, since you seem to talk about Excel parsing, but at the same time you mention choices, which in my opinion relate to Forms.
IMO you should handle directly the relationship to your entity, instead of only its id. Most of the time it is always better to have directly the related entity as attribute of your class A than only the id, and Symfony manipulates such behaviours pretty well.
Then just have your Excel parser do something like this:
$relatedEntity = $this->relatedEntityRepository->find($entityId);
if (!$relatedEntity) {
throw new \Exception();
}
$entity->setRelatedEntity($relatedEntity);
After doing this, since you were talking about Forms, you can then use an EntityType field which will automatically perform the request in database. Use query_builder if you need to filter the results.

Entity Framework 5 - Invalid column name - Reverse Engineer Code First

Using Entity Framework 5, Visual Studio 2010 with the Entity Framework Power Tools (Beta 2) extension.
Here is my database table structure:
I used the Reverse Engineer Code First function of the aforementioned extension, which generated the POCO classes and some 'mapping' files (not sure if that's the formal parlance) and a single DbContext-derived class. Other than the change I describe next, all of these generated classes are as-generated by the power tool.
In the Category.cs file, I added the following code to help flatten the object graph a bit:
private ICollection<Product> m_Products = null;
public ICollection<Product> Products
{
get
{
if (m_Products == null)
{
m_Products = new List<Product>();
foreach (var categoryProduct in CategoryProducts)
{
m_Products.Add(categoryProduct.Product);
}
}
return m_Products;
}
set { m_Products = value; }
}
I get the following exception, which I know must have something to do with the mappings, but I just can't quite figure this out.
Unhandled Exception: System.Data.EntityCommandExecutionException: An error occurred while
executing the command definition. See the inner exception for details.
---> System.Data.SqlClient.SqlException:
Invalid column name 'Category_CategoryId'.
If I need to post more information, such as the specifics of the mappings, just let me know and I'll do it. I wanted to keep this as short as possible, but I realize I've omitted some things that, for those unfamiliar with the code generated by the tool, may leave one wanting for more details.
You've added a navigation property to your model and so EF is trying to map that to your database. "Code First" means your code model defines your database schema.
Try adding the [NotMapped] attribute to your helper properties to tell EF to ignore them.
In case you've created DB scheme automatically and you are not using strategies like (DropDatabaseAlways/DropDatabaseIfModelChanges) - other words: you are really in Reverse Engineering, it seems that you have to manually add column "CategoryId" on "Category" table.
In case, you don't want to work with the property (I mean in DB), you can use Data Annotation [NotMapped] or Fluent API modelBuilder.Entity<Category>().Ignore(x=> x.CategoryId)
Finally it is possible that problem can be in mapping. I don't know whether you are using data annotations or Fluent API but EF may automatically looks for some db column (logical behavior derived from the model) and can not find it. In this case I recommend you make a revision of the mapping.
The OP already solved their problem, but I've had a similar error with a different solution. So here it is in case others need it:
I was missing a navigation property on one side of a 0..1 relationship between entities. Once I added an appropriate navigation property to the entity that was missing it, the problem was solved.
A bit more details: I had two entities with a 0..1 relationship using a FK. Entity A (parent) had a FK to Entity B (child). The child entity B had a navigation property to entity A, but A did not have a navigation property to B. After adding this, the problem was solved.

Use Entity Framework to Update only a few properties of a huge class

Scenario:
A huge Patient class/entity with around 100 properties. But in the webpage I only need to display the contact information (only around 10 properties) to update. Do/Can I create a ViewModel to do that?
I have only used ViewModel to read data before. Can it be used to update data?
EDIT:
Okay, to summarize what I have found so far.
Use AutoMapper to map the ViewModel (only contains the properties to be updated) back to the original big EntityClass.
An example is:
[HttpPost]
public virtual ActionResult Edit(EditUser user)
{
var domain = uow.Users.Create();
domain.Id = user.Id;
uow.Users.Update(domain);
AutoMapper.Mapper.Map<EditUser, Example.Core.Data.User>(user, domain);
uow.Save();
return View();
}
Create another entity called PatientSummary in the EDMX model, which only contain the necessary properties. Manually do the mapping in the EDMX designer. Then use this reduced entity for the Patient contact update web page.
Personally, I feel there must be a better way to do that. Any comment?
Yes upon save simply load your object and then use automapper to copy the properties back to your object or manually set them on your EF class.
EF will know which props changed and only send updatea for those changed properties.
I actually posted a couple of questions a little while back on a related topic - question 1 and more specific question 2.
I wasn't a hundred percent happy with the one answer that I got so far on question 2 but the experts seemed to agree that it is a good idea to use view models. For one it saves you from manually making sure that the "other" 90 properties don't get overwritten in the database by the generated UPDATE statement.

Bind customizable views to dynamic models

We are working on an ASP.NET MVC 3 using ext.net and EF 4.
Data model is mapped using EF4.
Views’ content is rendered from customizable XML files.
Example: Within one view, I can display fields that are related to both objects “customer” and “order”, so from this view I can modify the customer data and also add a new order.
How can we bind the view to the custom model that contains 2 objects (customer and order)? Using non strongly typed views will require a source code that will check all different possibilities (If I remove/add a field to display from the XML file, object constructor and CRUD operations parameters will change also.
We are wondering how can we handle such dynamic application?
Is this a common issue that was raised before? Or is there any solution to use dynamic views bound to custom model (object, xml, etc.)?
Your help is very appreciated, please enlighten me.
Based on what you replied to my comment, I can defenitely say that you need strongly typed views. That said, you decide what the model of your view is. If your view needs to manage users and orders at the same time, you can make a class like this:
public class MyCustomViewData
{
public IEnumerable<User> Users {get;set;}
public IEnumerable<Order> Orders {get;set;}
}
and then strongly type your view to MyCustomViewData and you're set. My example is oversimplified but I think you can get the point.
Unless I'm missing something, I believe the normal way round this would be to strongly type your view to say 'user' and then on the user object, define a property which is a collection of 'orders'.

how to json seralize entity framework many to many relationships without circular reference

I have 3 tables in my database - Conference, ActivityTypes and a joining table ConferenceActivities. Each conference may have a zero or many standard activities and each activity may occur in zero or more conferences.
Conference (ConferenceID, ConferenceName)
ConferenceActivities (ConferenceID,ActivityTypeID)
ActivityTypes (ActivityTypeID, ActivityTypeDesc)
I used Entity framework over my existing database, with the .tt templates in a MVC3 app I generated a DbContext and the POCO objects, noting that it generates just two objects, ActivityType and Conference which is nice it seems to understand the intermediary table.
It also adds a collection of activities to my conference
public virtual ICollection<ActivityType> ActivityTypes { get; set; }
And a collection of Conferences to my Activity.
public virtual ICollection<Conference> Conferences { get; set; }
I would like to return using JSON an object matching a specific conference.. that includes the ActivityTypes. Some might described this object as 'shaped' or 'jagged' because it has a collection within it.
I'm using code like the following although I've tried many different variations incase I had the syntax wrong but I still get a runtime error about recursion.
public JsonResult GetConference(int conferenceId)
{
Conference x = context.Conferences.Include("ActivityTypes").FirstOrDefault<Conference>(i => i.EventID == eventId);
return Json(x, JsonRequestBehavior.AllowGet);
}
It doesn't seem to work 'out of the box' and I see a lot of Stack Overflow questions that seem to relate but despite trying numerous different approaches but all create an error about recursion or parameterless constructors.. I am starting to doubt whether this is even possible.
I have tried attaching [IgnoreDataMemberAttribute] or [ScriptIgnore] to different properties to stop it trying to serialise the recursive relationship (I think the form is irrelevant but when your desperate..) and I still get the same error.
I've tried this sort of approach which generates the parameterless error
var thing = from r in context.Conferences
select new
{
r.ConferenceID,
r.ConferenceName,
ActivityTypes = new List<ActivityType>(
(from c in r.ActivityTypes
select new ActivityType()
{
ActivityTypeDesc = c.ActivityTypeDesc,
ActivityTypeID = c.ActivityTypeID
}).Cast<ActivityType>())
};
return Json(thing, JsonRequestBehavior.AllowGet);
Another suggestion was to set the Lazy Loading Enabled property on the model to false.. which made no difference I still get the recursion error.
I've tried removing the Virtual keyword which I belive turns off the lazy loading.. and trying with .Include(..) but again no joy.
Another suggestion was to change the accessor from public to internal however that made no different to the serialization.
Somebody also suggested removing the collection of Conferences from the ActivityType class, not really what I want to do.. but doing that just produces an error `Schema specified is not valid.' anyway.
I am using I believe the latest version nuget and the associated EF, scaffolding and templates.
Is what I'm trying to achieve something that should work out of the box? If so what setting(s) could I be missing and if not, what is the best practise here - the only way I know I can make this work is to build up the object manually myself.
Suggestions or a link to a complete working demo (I've seen a lot of suggestions and code snippets that just don't seem to work!!) appreciated. I'm certain somebody's done this and got it working surely.
don't pass your model classes around. create a viewmodel with the data you need for the view, or, in your case, the json output. i see where you tried projecting it into an anonymous type, but project it into a concrete viewmodel and it should work perfectly.

Resources