How to find the mapping tables in from the EF generated Classes - c#

I have a mvc 4 application which is entity framework database first based. Therefore lots of the classes are generated based on database tables via EF.
Currently, I created a method to retrive data from a table and display them in a dropdownlist, which works fine. However, I am thinking to modify that method to a generic type method, and passing the class type as the method parameter, and I would like c# code to find the mapping table in the database and retrive the data.
Following is my modified method
Thanks for your helps!
public static SelectList FromDbTableToSelectList<T>() where T: class
{
var db = new TableEntities();
//find the mapping database table
Dictionary<Guid, string> dic = db.MappingTable.ToDictionary(v => v.tableColumn1, v => v.tableColumn2);
return new SelectList(dic, "Key", "Value");
}

I don't understand your what your code does. However, there is a trick to find mapping table name (Entity Set Name in EF glossary) of an entity.
Suppose that you have a table in your db named Products. If you create your model with the Pluralize and singularize option checked, EF will create an entity class named Product.
Then, whenever you perform a query, EF naming convention thinks that your table name is dbo.Products. This is a general rule - in fact a naming convention.
From the other hand, if you uncheck the Pluralize and Singularize option, EF creates an entity class named Products for you and in this case, the class an the table have same names.
So, according to the selection of P&S option, you can infer table names from entity names and you don't need any code for it...

Related

Including a new table in the DBContext made with CodeFirst

We have a Data library they have built it with CodeFirst.
Now I ran a SQL command and added a new table to that database.
But Now I want to also see its generated object class, its DBContext definitions ,etc.. in the code first code so I can use them in my LINQ queries.
So what I did was following number 3 method from this MSDN page:
https://msdn.microsoft.com/en-us/library/jj200620.aspx
But it didn't do it right. For example it did not add any definition for this new table to DBContext.cs file, for example all my other tables that used to be there are defined like this:
DbSet<Zipcode> Zipcodes { get; set; }
But it has not added anything for me.
What is the correct way to do this?
I'm unaware of a way to simply add a new table and have it 'plug-n-play' with your existing model without manual work. The two options I know of are:
Rebuild the model using Code First from DB and include your added table
Manually create the table as a class and add the DbSet and entity in the OnModelCreating method in your model
Code First from Database only works when you already have a database. If you want to add a new table, you will have to start using Code-First(alone), that means: add the entity Zipcode to the model, DbSet to the DbContext and after that when you compile it will generate de table in the database.

How do I get an arbitrary entity stored in the context with Entity Framework?

I am using Entity Framework. I just need to get an arbitrary entity from the context so I can use reflection to look at its properties. I don't need any specific entity, any arbitrary one will do. My call should look like this:
Entity oldEntity = (Entity)_context.Set(newEntity.GetType()).
And some method should go after the last . but I don't see any that would work (find is my best bet but I can't use it since I don't know the ID's of any of the entities).
Edit:
I forgot to mention that the newEntity I am passing in is generated with a CodeDom class, so newEntity will be the same as the entities in the context, but it may have different properties, which is why I have to get an example "old" entity to compare its properties. To clarify this, imagine I have stored a Person entity with the properties:
First name
Last name
Then I want to add a new property, let's say Age. The way I'm doing this is by generating a new Person entity class with CodeDom with Age as an additional property. I have updated the entity class on disk, so I can create a new entity with the extra field, however my SQL table isn't updated.
You don't need an actual instance of a class to look at its properties.
You can just use typeof(...) like typeof(Entity).GetProperties()

How to map table names and column name different from model in onmodelcreating method in Entity Framework -6?

I have my database with table names starting with "tbl" prefix and column names like "ua_id" which are understandable in context of project but problematic if used in a model i.e names should be readable or meaningful(not like indicative names defined in database).
So I want to map them in my onmodelcreating method but I have no idea about it. I studied it in following blog:
http://weblogs.asp.net/scottgu/entity-framework-4-code-first-custom-database-schema-mapping
but this is for EF 4.1 and method doesn't work for EF 6.(mapsingletype method)
I want to map my tables by columns to my model as I can't change the column names. I just want the newer version of that syntax in the blog.
Thank You.
If you are using Code First, you can simply decorate your model with Table and Column attribute and give it the database names.
[Table("tbl_Student")]
public class Student
{
[Column("u_id")]
public int ID { get; set; }
}
These attributes are available in the System.ComponentModel.DataAnnotations.Schema namespace
You can keep following inside OnModelCreating
modelBuilder.Entity<MyModel>()
.Property(e => e.MyColumn).HasColumnName("DBColumn")
And if you're not using code-first, just select a table in the model diagram, hit F4 (properties) and change the name.

Get EF Table by type (parameter)

I have this very old database with all the tables named like this ANAGT*postfix* and all the columns are namede like this *prefix*_*column name*.
I have to query all the tables with the same query more or less, but obviously the names of the columns are all different so I would have to do some trick with a sql statement with the strings, but I prefer to get a strong typed exception in case of errors using the EF.
So I've created some interfaces and implemented them on partial classes from the EF model
public partial class *table name* : IIdentificable, ICountabile {}
IIdentificabile means that there's a method with a common name that gets all the ids (instead of query *prefix*_ID), so when I'll have to query the table I'll just have to do
var result = from elem in myContext.[Table]
where elem.GetId() == 1
select elem;
I've created a generic method that gets all the types from a certain interface (IIdentificable for instance) and now I have to get the EF table by type.
var tablesType = typeof(myModel).Assembly
.GetExportedTypes()
.Where(t=>t.IsAssignableFrom(typeof(T)));
foreach(Type t in tablesType){
var query = from elem in myContext.GetTable(t) //and here's what I can't do
select elem.GetId() == 1
select elem;
}
I think another approach may be better. In the EF Model you can rename the C# Objects and properties. Using the properties of a selected property in the model, you can change the Name to get rid of the prefix. Similarly, the properties of a selected table in the model allow you to change both the Entity Set name (the name of a collection of them) and the Name of the C# class. The names of the underlying database tables and columns aren't affected.

Accessing a Common Code Value Table in Generated EF Models

I have a database that uses a custom model for recording lookup valus (i.e. states, types, etc.). So across all of the database tables, there are various columns called something like state_cdv_id which would store an integer and reference the code_value table to get that state's value (i.e. "CA", "AK", etc.).
I would like to map my EF model so that I can access the code values for all of these fields, and I don't want to have to do it manually in partial classes for EVERY entity... that's a lot of repetition. So I want to be able to access my code values like: MyPerson.State and get back the string "CA" for example.
Here's what a single getter would be that I would have to repeat many times if I were to do it manually:
public string State
{
get
{
MyEntityContext c = new MyEntityContext();
return c.CodeValues.Single(cv => cv.Id == RecordStatusCdvId).Value;
}
}
I don't know what the best approach would be: change the T4 templates, add property attributes to certain fields and then programmatically add a getting to those, or something else.
Any help?
If there is a 1:1 relationship between the entity and the code_value table the entity should already have a State property, which by default which will be null by default, you could then fill it in by using an Include on your DB queries:
var foo = context.MyEntities.Include( x => x.State);
Your sample code is terribly wrong because it makes your entity dependent on the context (moreover you don't dispose it). Whole POCO approach just to avoid this (POCO T4 generator and DbContext T4 generator).
If you have relation to lookup table in your database EF will crate for you navigation property. If you don't have such relation in the database and you are using EDMX file you can still create such relation in your model and you will again get navigation property to lookup table. Once you have navigation property you can simply do:
string code = myEntity.State.Code;
But the navigation property must be loaded either by eager loading (as #BrokenGlass described) or by lazy loading.
If you don't like the idea of navigation property and you still want State property to show just code of the state you must understand what does it mean: If you map the entity that way it will be read-only because EF will not be able to transform compound entity back to real tables which must be updated. It is possible to map the entity the way you want but it is considered as advanced (and mostly not needed) scenario which works only if you have EDMX file (not with code first approach). The choices are:
Create database view and map the view to a new entity
Create DefiningQuery manually in EDMX (opened as XML) file and map it to a new entity (once you do that you cannot update your model from database or generate database from model any more)
Create QueryView manually in EDMX (opened as XML) file and map it to a new entity (this requires original entities to be already mapped)
You will have to do that for every table where you want such mapping. Anyway whole that complexity with manually changing EDMX is not needed because you can simply create custom classes like:
public class SomeViewModel // I suppose your main target is to have codes in presentation layer
{
public string SomeData { get; set; }
public string State { get; set; }
}
and use projection query
If you have navigation property:
var data = from x in context.SomeEntities
select new SomeViewModel
{
SomeData = x.SomeData,
State = x.State.Code
};
If you don't have navigation property
var data = from x in context.SomeEntities
join y in context.LookupValues on x.LookupId equals y.Id
select new SomeViewModel
{
SomeData = x.SomeData,
State = y.Code
};

Categories

Resources