Changing the Nhibernate entity to point to new table - c#

I am using FLH and recently I changed the name of the table. I dont want to propagate the changes all the way across my layers. Is there a way, where I can retain the same entity name and just change the mapping. For example, my current entity name is Issuer and the table name is also issuer. However, the table name is changed to "counterparty" and I want to retain the entity name as Issuer. How can I achieve this?
I found the answer for the above problem. I made use of IAutomappingOverride interface.
The sample code is below
public class IssuerMap : IAutoMappingOverride<Issuer>
{
public void Override(AutoMapping<Issuer> mapping)
{
mapping.Table("Counterparty");
}
}
Also found some related links
Fluent Nhibernate - How to specify table name

You would need to have a Table("Counterparty") clause in your classmap, as in How to specify table name in Fluent NHibernate ClassMap class?

Related

Mapping table name in Entity, when you define Code-First by existing Database

I already have defined my Database, and now I'm doing Code-First, creating the Objects so they fit with the current database.
My only problem is that the mapping table names dont entirely aggree with me.
My primary table is "Movies". Then I have a many-to-many to "Actors", and another many-to-many to "Genres".
My problem is >
The mapping table name for Actors is totally fine.. Entity aggrees with "MovieActors", BUT! The Genre table, Entity wants to call "GenreMovies".
Why does entity want this? And how can I force it to use "MovieGenres"?
Please let in mind that I have already created the Database, and dont want entity to create any tables.
If your class is named Genre, by convention Code First presumes this will map to a table named Genres. If that's not the case, you can specify the name of the table with the Table attribute. Here for example, the annotation is specifying that the table name is GenreMovies.
[Table("GenreMovies")]
public class Genre
Another option is use Fluent Api. The easiest way is overriding the OnModelCreating method in your Context:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Genre>().ToTable("GenreMovies");
}
If you want to change the name of that Table in DB, I suggest you learn how to use Code First Migration

How to specify the name of the table to be used by DbContext

This is a followback question from my earlier question. I was under the impression that if there're more than one table in the database, the name of the DbSet variable will be used to identify the table.
However in the linked question it was clear that the DbContext was choosing Products table instead of Portfolio table even if the name of the variable was Portfolio. I can still change the variable name to anything and I am still getting data.
So my question is how the tables are mapped by DbContext? I need to add few more tables in the project and have no idea how would I do that using a single DbContext object (or should I use separate DbContext for separate Tables in the same database)?
You can do the following on the entity:
[Table("Portfolio")]
public class Product { /* ... */ }
By convention the table is named after the plural of the entities name.
So a DbSet<Product> will by default be stored / looked up in a table named Products.
Take a look at System.ComponentModel.DataAnnotations.Schema.TableAttribute.
Specifically:
[Table("Portfolio")]
class Product
{
public string Foo{get;set;}
}

MVC4 code first force database column name

I have the following problem: I have a hierarchy of entities that uses inheritance. I have a two identical fields( the name and type is the same ) in two of the sub-entities. When I try to "Update-Database -Force" on the project EF5 complains that there are there is already a column with name X.
The way EF5 generates the tables is that it actually generates single table and puts there all the fields of the base entity plus the all the fields of the derived entities.
Is there a way to force a different database column name from the property name.
Are there any other solutions( I know it might be architectural problem to duplicate data but making this common will introduce more complex database hierarchy that I don't want to use ).
Thanks:)
This can be done in one of two ways, either using Fluent API or property attributes on your class properties.
[Column("ColumnName")]
public string PropertyName
{
get;
set;
}
See MSDN - ColumnAttribute Class for more details on the column attribute.
Otherwise, use Fluent API. Within your context class-
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<YourClass>().Property(yc => yc.PropertyName).HasColumnName("ColumnName");
See MSDN - HasColumnName extension method for more on this method.
The article linked by Baximilian will be useful in learning more about this.
If I understand you correctly, you need to change column name in DB for field, so you can use ColumnAttribute.
You can find more information here

Entity Framework - change display name of tables/entities

As the title suggests, I was wondering if it's possible to change the display name of my tables across all of my application.. currently my tables from my DB have complicated names and was wondering if I can change the display name so that it's more user-friendly.
Is there a class I can create that would do that for me?
I've looked at the following thread but not sure if this applies to my scenario.. I'm new to EF :)
Thanks!
Additional Info:
I'm using the database first approach and currently have an EDMX setup.
If you are using the Code-first approach, you should check the answer from Vitor M. Barbosa. If you are using Database First (has an EDMX), you can achieve that by changing the Name of the table/entity in your diagram. Internal EF will map that name to the table in the database.
If you're doing code-first, you'll just need some data annotations, e.g.:
[Table("TableName")]
public class Table
[Column("BlogDescription", TypeName="ntext")]
public String Description {get;set;}

Entity Framework table-per-type inheritance - adding inherited type to database giving error "Invalid column name"

I've been at this for a while, and I really cannot figure it out. I'm using EF5, Mvc 4, table-per-type inheritance.
I have classes Tenant and Landlord that inherit from UserProfile. When registering a user selects what account type they want, and based on this selection the details they enter on the form (username, first name, last name, email, account type, password) should be added to UserProfile table. I then want the PK of that table to be added as a foreign key to table that matches the account type they selected, either Tenant or Landlord.
I was trying to achieve the above using this method, but that resulted in the problems described in that question.
I've now created a RegisterTenantModel class, with properties that map to a Tenant, and I'm passing an object of type RegisterTenantModel to the AccountController/Register like so...
// ...
if (tenantModel.AccountType == AccountType.Tenant)
{
using (var db = new LetLordContext())
{
var t = db.UserProfile.Create<Tenant>();
WebSecurity.CreateUserAndAccount(tenantModel.UserName, tenantModel.Password,
t = new Tenant
{
AccountType = tenantModel.AccountType,
DateWantToRentFrom = DateTime.Now,
DateWantToRentTo = DateTime.Now,
DesiredPropertyLocation = "",
Email = tenantModel.Email,
FirstName = tenantModel.FirstName,
UserId = WebSecurity.CurrentUserId,
UserName = WebSecurity.CurrentUserName
// More properties that map to Tenant entity
// ...
},
false);
db.SaveChanges();
...but now I'm getting an error Invalid column name for each of the column names inside t= new Tenant.
Has anyone ever had to do something similar? Am I approaching this the right way? Help would be much appreciated.
EDIT
Based on what Antonio Simunovic posted below, I think I've come to realise what the problem is. My WebSecurity.InitializeDatabaseConnection() goes like this...
WebSecurity.InitializeDatabaseConnection("LetLordContext", "UserProfile",
"UserId", "UserName", autoCreateTables: true);
...so when I call Websecurity.CreatUserAndAccount() in AccountController/Register it's writing to the UserProfile table as per the parameters in WebSecurity.InitializeDatabaseConnection(). Looking at the question linked above, you'll see that, based on the account type selected on the form, either a Tenant or Landlord will be added to the UserProfile table by calling...
var tenant = db.UserProfile.Create<Tenant>();
//...
db.UserProfile.Add(tenant);
db.SaveChanges();
...resulting in duplicate entries being added to the UserProfile table.
I think the solution is to create a new table, and point WebSecurity.InitializeDatabaseConnection() at it.
What does your WebSecurity.InitializeDatabaseConnection() method call looks like? That call identifies database table to store user data.
WebSecurity.CreateUserAndAccount() method does not use context to store supplied data, it simply maps object property names of third call argument to columns in table defined in InitializeDatabaseFile() method.
If you're not familiar with SimpleMembership mechanics, take a look at this article:
http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx
I saw exactly the same symptoms, and it was because I hadn't declared the base class as a DbSet<BaseClassName> on the DbContext.
(Counterintuitive, and I never need to refer to the collection of base class entities in my application, but there you go.)
I have seen this error when I forget to annotate the subclass with the table name in TPT.
[Table("Tenant")]
public class Tenant : UserProfile { ...
Could it be as simple as this?
EDIT
A quick search also recommends pairing down your fields in the Entity and adding them back in one at a time to see if a single field is to blame (and it will provide an error message that indicates many failed columns). This sounds a little suspect to me, but might be worth a try:
Entity Framework 5 Invalid Column Name error
Solution
Ensure that all derived classes are explicitly mapped to tables. Two simply ways to do this are:
TableAttribute class attribute: [Table("Tenant")]
ToTable Fluent API method: ToTable("Tenant")
Ensure that the base type is abstract.
Ensure that you are not calling the MapInheritedProperties configuration method for any tables. That method implies TPC.
Ensure that the base type is registered as part of the model. Two simple ways to do this are:
Add an accessor property to your subclass of DbContext:
public DbSet<UserProfile> Users { get; set; }
Override OnModelCreating in your subclass of DbContext and call DbModelBuilder.Entity:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<UserProfile>();
}
Explanation
As the error message indicates, Entity Framework appears to be looking for the "base" table's columns in the "derived" table. This indicates that it's trying to use "Table per Concrete Type" (TPC) inheritance rather than "Table per Type" (TPT).
Making Entity Framework use TPT is quite fiddly. If you very carefully study the example implementation at Inheritance with EF Code First: Part 2 – Table per Type (TPT), you might spot what you're missing. The follow-up article, Inheritance with EF Code First: Part 3 – Table per Concrete Type (TPC), summarises the required configuration as follows:
As you have seen so far, we used its Requires method to customize TPH. We also used its ToTable method to create a TPT and now we are using its MapInheritedProperties along with ToTable method to create our TPC mapping.
My experimentation has shown that the above summary is oversimplified. It appears that a single minor seemingly-unrelated configuration difference can cause an unexpected inheritance strategy to be used.

Categories