Entity Framework and property mapping from another table - c#

I need to map a standard property (string) for a class which is not available in table mapped for class but in another table.
public class Centre
{
public int ID;
public string Name;
public string DescriptionInfo;
}
Database contains two tables - one is Centre and another is InfoText.
With above case want to populate the Centre entity and filled the DescriptionInfo property from InfoText table. InfoText table might have other column on which filter needs to be applied since this table contains description for other entities.
Options available are make a view of tables or use inheritance. Don't want to use inheritance OR create view for same.
Is it possible some other to make that join and fill the description.

Related

How do I add multiple tables using one model and one view?

I want to have a page where the user selects from a drop down list the category, then adds a small text about that category and uploads an image where the path of that image is saved in the database rather than the whole image. I have created a table "Categories" where the admin is authorized to fill it and the user only selects from the categories list.
Here is what I have done so far:
The create categories model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace DemoIdentity.Models
{
public class CategoriesAdmin
{
public int ID { get; set; }
[Required(AllowEmptyStrings = false)]
[Display(Name = "category name")]
public string categoryName { get; set; }
}
public class DefaultConnection:DbContext
{
public DbSet<CategoriesAdmin> categories { get; set; }
}
}
Now I want to have another table (Data) which includes (ID, Category (category name selected from table categories), News, Image_Path). This table is in the Default Connection database. The category name is the selected category name from a drop down list, and the image path is an upload image which saves the path rather than the whole image.
I am unsure of how to achieve this.
It appears that you are confusing components of ASP.NET MVC and Entity Framework.
As the Entity Framework site states:
Entity Framework (EF) is an object-relational mapper that enables .NET
developers to work with relational data using domain-specific objects.
It eliminates the need for most of the data-access code that
developers usually need to write.
And the MVC site states that:
The ASP.NET MVC is an open source web application framework that
implements the model–view–controller (MVC) pattern.
The two frameworks meet through your model classes. MVC uses the model class to define the data, logic and rules of the application. In Entity Framework, your model class is mapped to tables in your database where it handles the direct reads and writes for you.
By creating your CategoriesAdmin model class and exposing it as a property in your DbContext class as such:
public class DefaultConnection:DbContext
{
public DbSet<CategoriesAdmin> categories { get; set; }
}
Entity Framework will have mapped your model class to a database table called CategoriesAdmins. If this table does not yet exist in your database, it will automatically create it for you. This approach in Entity Framework is known as Code First to a new Database.
Now since you already have a table that stores the available categories (CategoriesAdmin), you will need to create a second model class (called Data for the sake your example) which contains properties for the other bits of information that you want to store.
public class Data
{
// gets or sets the ID of this Data record.
public int ID {get;set;}
public string ImagePath {get;set;}
// other properties
...
}
Now that you have two model classes, you need to create a relationship between the two. In a SQL database this is achieved by Foreign Keys. In Entity Framework, you can achieve the same by using Navigational Properties.
So we update the Data model class as such:
public class Data
{
// gets or sets the ID of this Data record.
public int ID {get;set;}
public string ImagePath {get;set;}
// gets or sets the ID of the related CategoriesAdmin record.
public int CategoriesAdminId {get;set;}
// gets or sets the related CategoriesAdmin record. Entity Framework will
// automatically populate this property with an object for the related
// CategoriesAdmin record.
[ForeignKey("CategoriesAdminId")]
public virtual CategoriesAdmin CategoriesAdmin {get;set;}
// other properties
...
}
The ForeignKeyAttribute on the CategoriesAdmin property is there to give Entity Framework a further hint of the foreign key column to load the navigational property from.
Finally to be able to use your new Data model class with Entity Framework, you need to add another property to your DbContext class so that you have a means of accessing your data:
public class DefaultConnection:DbContext
{
public DbSet<CategoriesAdmin> Categories { get; set; }
public DbSet<Data> Data { get; set; }
}
Now that you have created your model classes and wired them into Entity Framework, you will now be able to use them in MVC. If you load your Data model into your view (using DefaultConnection.Data), you will be able to access the related CategoriesAdmin record by accessing the CategoriesAdmin property on the Data object.
In short: two tables means you need two models. Both models can be loaded into the single view.
Footnote: Apologies if there are large gaps in my answer as there is a lot to explain that have already been explained in other places far better than what I can. The references I have linked should hopefully fill in the gaps.
Should you need more help, please see all of the tutorials on the ASP.NET MVC website on working with data. They're much better written than my concise attempt. I would recommend following them exactly and getting the examples to work before completing your own project so that you have a better understanding of how the two frameworks work and interact with each other.

EF CodeFirst mapping enum with custom value mapping

I need to create an application that is compatible with various legacy database systems.
So, the database exists, but I still want to use code first to be independent from whatever database is used as datastore. For each deployment, I intend to create a "mapping" library containing the correct FluentAPI mappings of the entities to the database.
I'm using EF6.
I don't want code first to alter anything in the database structure automagically, so I use
Database.SetInitializer<mycontext>(null);
Now I'm stuck on following issue:
my code defines an enum Gender, which is used as a property in the Person entity
public enum Gender
{
M = 1,
F = 2
}
However, in one of the legacy databases, the values are the other way around. The table "Gender" exists, and the lookup data in that table is ID 1 = female, ID 2 = male.
The Person table has a "FK Gender ID" column.
How would I configure through Fluent API the mapping of the Gender property of my Person entity, to the Person table in the legacy database table.
modelbuilder.Entity<Person>()
.Property(c => c.Gender)
.HasColumnName("FK Gender ID") //--> and how to "inverse" these values here ?
Is this possible with Fluent API, and if not, is there a workaround ?
Thanks.
I don't think that something you are trying to do is possible. For simplicity you should consider changing your code to match what you have in your database. If you cannot do that here is what you can do. Define an enum type (something like GenderDb or something). Ideally no one should even see this enum. Then create private properties of GenderDb type and map them to database columns (I believe in EF you can map columns to private properties). Again the properties are private so that no one can see them. Then add public properties of the Gender type on the entities that have the private GenderDb properties. The public properties should be configured as not mapped/ignored. Now implement the setter and the getter of the public properties so that it converts the value accordingly (i.e. setter converts the Gender enum to GenderDb and sets the private property, getter reads the private property and converts GenderDb to Gender).
(Yes you could get away with just one enum type if you like to receive phone calls at 2 am)

Bind Scalar Property at DataEntity(DataEntity Framework)

folks, i am new to C# DataEntity Framework.
I have 2 tables in DB :
Vehicle with fields id, measurementId.
Measurement with fields Id, Name.
They related as one to one. One vehicle have one measure.
I want to expand entity Vehicles where i want to store MeasurementName field. I've created property MeasurementName, but how i can bind it to Measurement.Name. Is it possible in DataEntity framework ?
I know that i can achive it another way, for example using Entity Linq where i will create new
class Test
{
Id= id,
Measurement = measurement.Name
};
But is it possible to expand DataEntity to have this property ?
Each of the entities in your model is implemented as a partial class, meaning the total code that defines the class can exist in multiple files but gets compiled into one object. This makes them highly extensible as you can add properties and functions to the code generated by the Entity Framework designer. Create a new partial class with the same name as your entity in the same namespace and add the custom property like so
public partial class Vehicles
{
public string MeasurementName {
get {
return this.Measurement.Name;
}
set {
this.Measurement.Name = value;
}
}
}
If this answer was helpful to you, please be certain to vote it up or mark it as the accepted answer.

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
};

how to populate an entity you have extended in the Entity Framework?

I have an entity in my EDMX that I've extended with a few fields in a partial class like this:
public partial class Employee
{
public string JobName {get;set;}
}
These properties are for display only. In the above example say the entity has a JobTypeID property. I wish JobName to be populated w/ the name that belongs to that JobTypeID.
Is there anyway to query the employee record in EF including the value for the JobName property w/o explicity assigning each field using select()?
The reason I ask is that there are a lot of fields in the Employee entity so I'd like to be able to take advantage of something like:
ctx.Employees.Where(e=>e.EmployeeID==employeeID).Single()
...add somehow fill in JobName too
Is this possible?
How about: public string JobName { get { return this.JobType.Name; } }?
Not a solution, but a different approach to what you are trying to achieve...
Why not use the power of EF! use "Include" to load the relation based records from related tables?
You can do that in a single place as well, say if you want a JobType record per Employee record, you may consider using a repository pattern and add all possible includes for your entities which depend on each other!
Some thoughts further on what I mentioned, not exactly as I said but...
http://mosesofegypt.net/post/Introducing-DataLoadOptions-for-Entity-Framework-ObjectContext.aspx

Categories

Resources