How to cast Entity framework Objects in Web API? - asp.net-mvc-4

I'm using entity framework and I figured out that it ain't able to serialize the output of
EDM Objects. For now I'm using Northwind Products-table. SO thereforth I'm forced to cast the Object to another and are using the .Cast but it doesn't work.
The only solution I have is to property by property do it manually in my code, but I'm thinking - there must be a better way!
For god's sake - it is 2013! And this Entity seems like a good idea in the beginning but it has so many gotchas and constraints that it actually hinders more than it helps, but anyway the EDMX diagrams are nice!
Anybody who has a better solution to casting the objects?
POCO
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
//public Nullable<int> SupplierID { get; set; }
//public Nullable<int> CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
public Nullable<short> ReorderLevel { get; set; }
//public bool Discontinued { get; set; }
public Category Category { get; set; }
//public ICollection<Order_Detail> Order_Details { get; set; }
//public Supplier Supplier { get; set; }
}
View Model
public class ProductsViewModel
{
public List<POCO.Product> Products { get; set; }
public ProductsViewModel()
{
using (NorthwindEntities dNorthwindEntities = new NorthwindEntities())
{
this.Products = dNorthwindEntities.Products.Cast<POCO.Product>().ToList();
Web api controller:
public class ProductsController : ApiController
{
public List<Product> GetAllProducts()
{
var viewmodel = new ProductsViewModel();
return viewmodel.Products;
}

1.
You can use frameworks like AutoMapper to handle Entities to ViewModel / DTO mapping automatically.
2.
Using Entities in the View (even in their POCO form) is not recommended for couple of reasons:
Security: Sending entities back to the client/view may expose more data than you intended.
Serialization: Since your entities usually contain reference to another entities and those entities may contain a reference back to the (parent) entity, you have to configure your serializer to handle this situation otherwise you'll get Circular Dependency Exception.
Incompatibility: The structure of your entity may not be compatible with what your view/client needs to render itself. Sometimes your view just needs a simple string while the entity holds this data in a much complex way hence the view needs to 'extract' it and you end up with a view full of unnecessary entity-drill-down code.

Related

ASP.NET MVC 4 database scaffolding self referential model

I have a constructed a model using code first in C#. The model literally represents a container element for a website building application, in other words, the model defines a Div tag or some such HTML element. Like a Div tag which can contain multiple child elements, I have tried to represent this in my model, but the scaffolding to the DB, does not give me what I'd expect.
I should get a new many to many joins table, but instead I only get a single column in the DB which expects a single int data type.
Here is the model:
public class ElementContainer
{
public int ElementContainerID { get; set; }
public int PageId { get; set; }
public int? ParentElementContainerID { get; set; }
public string ElementContainerName { get; set; }
public ElementType ElementType { get; set; }
public string ElementClass { get; set; }
public PageAsset PageAsset { get; set; } // content of container
public List<ElementContainer> NestedContainers { get; set; }
}
The last line is the self-referential attribute which just appears as a column called ElementContainer_ElementContainerID
Thanks in advance!
I agree with Bahman, DB first is easier.
While I haven't tried to do what you are trying, your code looks like a self-Join that would do exactly what you describe.
This is a One-to-Many relationship. EF Navigation will pull a List of all nested children containers.
If you want to create a many-to-many relationship with EF Code-First, you should create another Entity
public class ContainerChildren
{
public int ElementContainerID { get; set; }
public List<ElementContainer> NestedContainers { get; set; }
}
this reference should help you to get the exact idea http://blogs.msdn.com/b/wriju/archive/2011/05/14/code-first-ef-4-1-building-many-to-many-relationship.aspx

Parameter xxx of domain operation entry xxx must be one of the predefined serializable types

I get this webservice error sometimes on a SL5 + EF + WCF app.
"Parameter 'role' of domain operation entry 'AddUserPresentationModelToRole' must be one of the predefined serializable types."
here is a similar error, however his solution doesn't work for me.
I have the codegenned DomainService which surfaces the database entities to my client:
[EnableClientAccess()]
public partial class ClientAppDomainService : LinqToEntitiesDomainService<ClientAppUserEntitlementReviewEntities>
{
public IQueryable<Account> GetAccounts()
{
return this.ObjectContext.Accounts;
}
//..etc...
and my custom service which is surfacing a Presentation model, and db entities.
[EnableClientAccess]
[LinqToEntitiesDomainServiceDescriptionProvider(typeof(ClientAppUserEntitlementReviewEntities))]
public class UserColourService : DomainService
{
[Update(UsingCustomMethod = true)]
public void AddUserPresentationModelToRole(UserPresentationModel userPM, Role role, Reviewer reviewer)
{
...
}
public IDictionary<long, byte> GetColourStatesOfUsers(IEnumerable<RBSUser> listOfUsers, string adLogin)
{
//....
}
}
and the PresentationModel:
public class UserPresentationModel
{
[Key]
public long UserID { get; set; }
public byte UserStatusColour { get; set; }
public string MessageText { get; set; }
[Include]
[Association("asdf", "UserID", "UserID")]
public EntityCollection<Account> Accounts { get; set; }
public DateTime AddedDate { get; set; }
public Nullable<long> CostCentreID { get; set; }
public DateTime? DeletedDate { get; set; }
public string EmailAddress { get; set; }
public long EmployeeID { get; set; }
public string FirstName { get; set; }
public Nullable<bool> IsLeaver { get; set; }
public string LastName { get; set; }
public DateTime LastSeenDate { get; set; }
public string LoginDomain { get; set; }
public string LoginName { get; set; }
public byte WorldBuilderStatusID { get; set; }
}
Also cannot get the solution to reliably fail. It seems whenever I change the service slightly ie make it recompile, everything works.
RIAServices unsupported types on hand-built DomainService - seems to be saying the same thing, that decorating the hand built services with the LinqToEntitiesDomainServiceDescriptionProvider should work.
Possible answer here will post back here too with results.
From Colin Blair:
I am a bit surprised it ever works, I don't think I have seen anyone trying to pass additional entiities into a named update before. It might be a bug in RIA Services that it is working at all. What are you trying to accomplish?
Side note, you have a memory leak with your ObjectContext since it is not getting disposed of correctly. Is there a reason you aren't using the LinqToEntitiesDomainSerivce? It would take care of managing the ObjectContext's lifetime for you.
Results:
1) This makes sense. Have refactored out to more sensible parameters now (ints / strings), and all working.
2) Have brought together my 3 separate services into 1 service, which is using the LinqToEntitiesDomainSerivce. The reason I'd split it out before was the assumption that having a CustomUpdate with a PresentationModel didn't work.. and I had to inherit off DomainService instead. I got around this by making a method:
// need this to avoid compile errors for AddUserPresentationModelToRole.. should never be called
public IQueryable<UserPresentationModel> GetUserPresentationModel()
{
return null;
}

DbDataController in MVC4 UpdateEntity failing

I have a datamodel like
ModelA which contains a Collection.
ModelB contains a Collection as a backreference. That is failing because of cyclic references if I query with Include("ModelB"). Not good but I solved that via setting ModelB.List=null for each element.
The problem now is submitting a changed ModelA tree: I am adding ModelB-entities to ModelA.ModelB[]. Now the UpdateEntity function is complaining the it could not add elements of type ModelB which are declared static. The JSON deserializer is creating static arrays.
How is it possible with the combination of upshot/MVC4 to submit datamodels which are not completely flat? As it is not possible right now to create your own DTO objects where you might figure out something I am stuck now...
After investigating the error a bit better, I think the problem is the cyclic backreference:
The ModelA->ModelB->ModelA is breaking the storage of the data. "Could not add data of type ModelA to type ModelB".
As I mentioned the backreference was set to Null because the cyclic ref serialisation problem...
I hope the will be some easier way on doing more manually with DTO objects where I have mroe control.
Please see also: MVC 4, Upshot entities cyclic references for the beginning of the journey...
To solve the cyclic backreference, you can use the ignoreDataMember attribute:
public class Customer
{
[Key]
public int CustomerId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public virtual ICollection<Delivery> Deliveries { get; set; }
}
public class Delivery
{
[Key]
public int DeliveryId { get; set; }
public string Description { get; set; }
public bool IsDelivered { get; set; }
[IgnoreDataMember]
public virtual Customer Customer { get; set; }
public virtual int CustomerId { get; set; }
}
I posted a working solution to your problem in a different question: https://stackoverflow.com/a/10010695/1226140

Automapper and NHibernate lazy loading

I am struggling with this issue:
I have a list of NHibernate objects called "Project". These objects contain a lazy - loaded list of "Branches". I am trying to pass a list of Projects to a WCF service so I am using AutoMapper to transform them to flat objects.
The problem is that even though the destination objects called "ProjectContract" does not contain a list of Branches, Automapper still invokes this collection and a lot of queries are made to the database because NHibernate fires the lazy - loading and loads the Branches collection for each project.
Here are the classes and the mapping:
public class Project
{
public virtual int ID
{
get;
set;
}
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual IList<Branch> Branches { get; set; }
}
[DataContract]
public class ProjectContract
{
[DataMember]
public virtual int ID
{
get;
set;
}
[DataMember]
public virtual string Name { get; set; }
[DataMember]
public virtual string Description { get; set; }
}
public class ProjectMappings : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Project, ProjectContract>();
}
}
My question is: Is there a way to tell AutoMapper to not touch the "Branches" collection because I don't care about it and that is a proxy that will trigger many database calls?
I temporarily fixed this with MaxDepth(0), but there are other entities where I have collections that I want to transfer, and collections that I don't want to be touched, like this one. In that case, MaxDepth(0) will not work.
Thank you,
Cosmin
Yes, The AutoMapper Ignore function.
Mapper.CreateMap<Source, Destination>()
.ForMember(dest => dest.SomeValuefff, opt => opt.Ignore());

How to map multiple interface implementation using NHibernate

I searched a lot about how to map multiple inheritance or multiple interface implantation using EntityFramework or NHibernate But I didn't find anything useful.
I Simply want to map this structure using NHibernate:
public interface IA
{
string A { get; set; }
}
public interface IB
{
string B { get; set; }
}
public class C : IA, IB
{
string A { get; set; }
string B { get; set; }
}
As far as i know mapping this structure to a relational database means just to have foreign keys related with the interfaces primary keys, therefore the interfaces should have Keys like these:
public interface IA
{
Guid AId { get; set; }
string A { get; set; }
}
public interface IB
{
Guid BId { get; set; }
string B { get; set; }
}
public class C : IA, IB
{
public virtual Guid AId { get; set; }
public virtual Guid BId { get; set; }
public virtual string A { get; set; }
public virtual string B { get; set; }
}
But how to map this structure using NHibernate Or EntityFramework,and I don't know why multiple interface mapping is not mentioned in their documentation!
In NHibernate, you'll just map C as if the interfaces didn't exist.
You'll still be able to query on the interfaces, thanks to implicit polymorphism.
You will map it as any other class because this is not inheritance mapping. Moreover your code cannot be compiled because you must implement all properties in class C so you will get:
public interface IA
{
Guid AId { get; set; }
string A { get; set; }
}
public interface IB
{
Guid BId { get; set; }
string A { get; set; }
}
public class C : IA, IB
{
public virtual Guid AId { get; set; }
public virtual Guid BId { get; set; }
public virtual string A { get; set; }
}
Now your code can be compiled and you have class as any other. You will map AId and BId as composite key (depending on used ORM) and you are done. This is not inheritance because you have just single entity and no base enity. At least this is how it works with Entity framework.
As what I've founded it's not possible to have multiple inheritance in a relational database due to the concept and what Diego said is true in a "not interfaces get persisted scenario".