mvc 4 - c# - Entity Framework - Metadata using edmx file - entity-framework

I'm using Entity Framework edmx. When I update the edmx I lose my metadata.How do you create and use metadata properties (that are not real fields).

Create a Metadata folder in the project where is the edmx. Create a class with the name of your entity as bellow: And within the same file create another class with the name of your entity with the "metadata" extension (MyEntityMetadata).
namespace MyNameSpace.DataAccess //You need to use the same namespace of edmx entities files
{
[MetadataType(typeof(MyEntityMetaData))]
public partial class MyEntity //This is possible because entities files using partial class
{
[NotMapped] //System.ComponentModel.DataAnnotations.Schema
public int MyProperty { get; set; }
//more properties...
}
public class UsuarioMetaData
{
[Display(ResourceType = typeof(Resources.Global), Name = "MyFieldLabel")]
public int MyField { get; set; }
//More fields
}
}

Related

Entity Framework 6 load derived class of entity

In Entity Framework 6, given class A and derived class B: A, I would like to load entities A into instances of B without having to code for each property.
So given:
public class A
{
public Guid AId { get; set; }
public string Value { get; set; }
}
public class B: A
{
[NotMapped]
public string OtherValue { get; set; }
}
public MyDbContext: DbContext
{
public DbSet<A> As { get; set; }
}
I would like to:
using (MyDbContext db = new MyDbContext())
{
IEnumerable<B> Bs = db.As.LoadBsSomehow()
}
I'm guessing I could add DbSet<B> Bs { get; set; } and then in OnModelCreate I could override the table name to As perhaps. I'd like to avoid that if I can.
The purpose of doing this is that we need view models that need the underlying model plus some other properties and I don't want to mess up the models with all the different view model properties. This would simplify coding and maintenance for when the main model is changed -- the inheritance would automatically handle the changes in the derived class (view models).
I can then set the additional properties of the Bs in a Select or other method.
Also, I do NOT want to use reflection. I can code that up if I need it. I'd rather find out if EF 6 has the ability to do this natively.
UPDATE: I can do DbContext.Database.SqlQuery<T>. I would prefer to be able to use LINQ instead of writing SQL. I have no problem writing SQL, but LINQ is much more maintainable from a code perspective. Perhaps if I can use LINQ to create an IQueryable<B> and get the SQL for it?

Get table name from edmx using t4 templates

I am using database first approach. I already mapped my tables and have generated entities. In my edmx model I have changed table names so that my entity names are more readable. But now for some reason I need to get original table/column name for my entities. Is there anyway in which I can update tt file to get table/column names? (See desired code below).
// Current generated code for entity,
public partial class University
{
public int DepartmentCount { get; set; }
}
// Desired code for entity,
[Description("TABLE_UNIVERSITY")]
public partial class University
{
[Description("DEPARTMENT_COUNT")]
public int DepartmentCount { get; set; }
}

ASP.NET MVC4 Web API Controller serialization

I am trying to create a RESTful web service that returns a list of products using ASP.NET MVC4 Web API. Here is my controller class
public class ProductController : ApiController
{
public IEnumerable<Product> GetProducts()
{
WebCatalogContext dbcontext = DatabaseConfig.Instance.Context;
List<Product> plist = dbcontext.Products.ToList();
return plist;
}
}
When I run my service and call the following URL from my browser :/api/Product, I get System.Runtime.Serialization.SerializationException. I looked into my plist object and there is no problem with it.
Here is my data model:
[DataContract(Name = "p")]
[Serializable]
public class Product
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DataMember(Name = "id")]
public int Id { get; set; }
[Required, MaxLength(50)]
[DataMember(Name = "ti")]
public string Title { get; set; }
[Required]
[DataMember(Name = "de")]
public string Description { get; set; }
[Required]
[DataMember(Name = "ph")]
public string PhotoURL { get; set; }
[DataMember(Name = "ca")]
public virtual ProductCategory Category { get; set; }
}
[DataContract(Name="pc")]
[Serializable]
public class ProductCategory
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DataMember(Name="id")]
public int Id { get; set; }
[DataMember(Name="nm")]
public string Name { get; set; }
}
When I remove the reference to ProductCategory from my Product class, all things work just fine. But, when I include it I get the following exception.
Type 'System.Data.Entity.DynamicProxies.Product_664E9A0AA1F165A26C342B508BFFF1279FD3FE059285225BDA19F407A29A9CAD' with data contract name 'Product_664E9A0AA1F165A26C342B508BFFF1279FD3FE059285225BDA19F407A29A9CAD:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Any idea about what I am missing?
Regards
Entity Framework has wrapped your POCO with an EF Proxy POCO so it can perform lazy loading - this uses the Virtual attribute to create a 'lazy-loadable' navigation property. I expect that is where the serialization error comes from.
You could make a new class and map the POCO to that - then pass the DTO style class from the controller. I've never returned an EF object directly from the API (I always map to some something else) so I don't know another option.
EF POCO to DTO (data transfer object) is relatively painless if you use a tool like http://valueinjecter.codeplex.com/ or http://automapper.org/
To support Lazy Loading for navigation properties which is declared as virtual, EF will generate the proxies for any models which have navigation properties which leads to this kind of exception.
For very simple application, you can use model from EF as DTOs (if having no navigation properties), but for complex application, you should do separate and differ between DTOs and domain models. It should not be mapping 1:1 between DTO and domain model.
Therefore, in your case, you create more DTO model for Web API layer, it will be fine.

How do I configure my DbSet to map to a specific table within a specific SqlServer Schema?

The database I need to build a DAL for is designed with multiple schema, which is causing me some problems:
So, for example, consider these tables within two separate Schema (Suppliers, Deals)
Suppliers.Suppliers
Suppliers.Types
Deals.Deals
Deals.Types
I have in C#
namespace Data.Entities.Suppliers
{
public class Suppliers { /* properties mapped to fields in Sql Server table Suppliers .Suppliers */ }
public class Types { /* properties mapped to fields in Sql Server table Suppliers .Types */ }
}
namespace Data.Entities.Deals
{
public class Deals { /* properties mapped to fields in Sql Server table Deals.Deals */ }
public class Types { /* properties mapped to fields in Sql Server table Deals.Types */ }
}
namespace Data.Repositories
{
public class EfDataContext: DbContext
{
public DbSet<Suppliers.Suppliers> Suppliers { get; set; }
public DbSet<Suppliers.Types> SupplierTypes { get; set; }
public DbSet<Deals.Deals> Deals{ get; set; }
public DbSet<Deals.Types> DealTypes { get; set; }
}
}
but EF is tripping over there being two things named "Types", how do I disambiguate the two using only DbSet?
NOTES:
I am trying to get away from having a .edmx file.
To specify schema you can use TableAttribute on your class (http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.tableattribute(v=vs.103).aspx) or configure your model using fluent api with ToTable() method (http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.tableattribute(v=vs.103).aspx)

ADO.NET Entity Data Model - Adding custom properties

I am new to using the ADO.NET Entity Data Model tool. I have a table in my database that has three properties (FirstName, LastName, Age). I need to add a field to this entity called IsChosen. However, I cannot add this column in the database.
How do I add custom properties to entities generated through this tool?
Thank you!
The Entity Data Model tool creates partial classes.
You can extend those partial classes in another source file. You just need to make sure your section of the partial class lives in the same namespace as the Entity Data Model generated classes. For example:
Tool Generated Code
namespace Your.Generated.Classes
{
public partial class Stuff
{
public string Name {get; set;}
public int Age {get; set;}
}
}
Your Seperate Code File
namespace Your.Generated.Classes
{
public partial class Stuff
{
public string NonDatabaseProperty {get; set;}
}
}