How to change DbSchema for Entity Framework at runtime? - c#

We are using EF5.0 in our project and we are supplying the Db Schema name using following code in the OnModelCreatingevent
string schemaName = DbSchema;
modelBuilder.Configurations.Add(new TableMap(schemaName));
But our problem is that the OnModelCreating event is called only once(even if I create context object again) and we need to change the Db Schema name for different databases which we are processing in a loop.
I believe that EF 6.0 has a method like HasDefaultSchema but I am unable to find a way for EF5.0
Is there any way to achieve this?

The cleanest way is probably to use the DbContext's ctor overload that takes model [1]. That way you can create two different configurations (though different only in schema) and switch these as needed.
The model itself is represented by DbModel class and created by DbModelBuilder class. It's almost the same as in OnModelCreating method. You can easily parametrize this.
[1] I suppose you want to use one context. If not, you I would go for different context classes.

Related

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()

Insert Derived class as Base Class [duplicate]

I have created an entity data model and generated a database from it.
One of the entities is called Template.
Created partial classes to extend the functionality of Template works fine.
If I create a new class and try to derive from Template, I get a runtime exception upon instantiating:
Mapping and metadata information could not be found for EntityType 'Template001'.
How can I work around this? I definitely need to inherit from the EF classes.
EDIT
Does not seem possible. If that is the case, what would be the best way to implement the following requirement: The template entity stores information about templates that each have their own code to execute. That is why I was trying to derive from the entity in the first place.
It is not supported. You cannot derive a new type from entity and use it instead of the mapped entity type for persistence. If you want to have derived class from entity you must use mapped inheritance where every child is also mapped to the database.
Why do you need to inherit from entity class first of all? If you want to add some simple behavior, use partial class.
Update: Based on comments, it appears that there is possibility that behavior will be extended over the time. In this case, I would recommend using composition/aggregation, not inheritance. Let the classes that need to be extended have an entity as a field. In Raheel's scenario, it would be a class called TemplateLogic with field/property of type Template.

How can I get the list of entity types from an ObjectContext at runtime using EF code first?

I'm trying to write some extensions on top of EF and I need to be able to inspect a code first ObjectContext and retrieve the entity types in it. I feel like this should be available somewhere in the metadata workspace, but I'm not sure where to look. I'm using EF 5.
Note that we don't use any kind of code generation to create our contexts, nor do we put type-specific DbSet accessors on the DbContext base class. Thus, I can't simply reflect over the DbContext/ObjectContext to look that such properties.
I think this should work:
var objectItemCollection =
(ObjectItemCollection )((IObjectContextAdapter)ctx)
.ObjectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace);
foreach(var entityType in objectItemCollection.GetItems<EntityType>())
{
Console.WriteLine(objectItemCollection.GetClrType(entityType).FullName);
}

Invalid object name 'dbo.TableName' when retrieving data from generated table

I'm using entity framework code first to create my tables. Please note - create the tables, not the DB, since I'm working on a hosted environment and I don't have a user that is allowed to create db's.
Committing a DB update works fine, but retrieving data gives the exception:
Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.EventHosts'.
I've read that it happens because I'm not using EF Code First to create the DB. That's fine, but how do I elegantly solve this?
All the generated tables do not have a prefix like dbo. A solution like this doesn't work, and isn't elegant at all:
[Table("EventHosts", Schema = "")]
Ok, for me issue was that I had a table called dbo.UserState and in C# EF was trying to access dbo.UserStates because of pluralization.
The solution was to put Table attribute above class and specify the exact table name:
[Table("UserState")]
public class UserState
{
[Key]
public int UserId { get; set; }
}
To answer your first question: use the schema created for you by your hosting provider.
To answer your second question: No there is currently no direct way to change the default schema globally because you cannot modify existing conventions or create new conventions. You can try to hack it.
For example you can override OnModelCreating and use reflection to get all DbSet<> properties declared in your context. Than you can just use simple loop on these properties and create ToTable mapping call with name of the property as table name and your custom schema. It will require some playing with reflection to make this work.
Alternatively you can try to do some reusable approach by implementing custom conventions. You can find many different articles about using your own conventions with EF. Some examples:
Custom Conventions in Entity Framework Code First v 4.1
Conventions in Entity Framework 4.1 Final
My high level untested idea is following same principle and create assembly level attribute which will be processed by the convention mechanism and applied on all your entities.
Try to set default schema name to 'dbo' in SQL SERVER.
http://msdn.microsoft.com/en-us/library/ms173423.aspx
On of the reason for this error is the table named "EventHosts" may not Exist or that table is renamed to some other name please check with that..
https://stackoverflow.com/a/12808316/3069271
I had same issue, it was pluralize problem between mapping and db.

Disabling Entity Framework's default value generation (Code First)

I have a column in the database that cannot be null, and I want to set it to have a default value in the database . The problem is that entity framework seems to create a default value itself (for example, int => 0), and completely ignores the default value constraint in the database.
Is there any way to disable this default valuing of entity framework?
I have found that you can decorate your fields with the following attribute.
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
Natively, Entity framework do not allows this. You have to do some code to it. This answer from another site seems to had solved the problem for many people.
He "hacks" it (as he told) by doing something like that:
public partial class YourEntityClass {
public YourEntityClass() {
this.PropertyNameWithDefaultValue = default(int);
}
}
Note 1 : Someone mention that it may not work in EF4
Personal note : Sorry for my english, I usually speak French.
Sometimes we need to do manually what EF doesn't do automatically for us.
In case using EF 4.1 "Code First", I usually create a separated class DbInitializer derived from IDatabaseInitializer, and in the implementation of the InitializeDatabase method, just call the
context.Database.ExecuteSqlCommand("ALTER TABLE TABLENAME ... ");
Now at the static constructor of the class derived from DbContext, just call the initializer:
Database.SetInitializer(new DbInitializer());
In this way, it's possible to specify any database DML/DDL commands to alter tables/columns just to make sure the DB is like we want.
"Computed" fields in EF are not the same as fields with default values in SQL. A computed field is one that is computed on the server and shouldn't be altered when an object is submitted. If you put a Computed tag on a field, you will get the default when you first create the object, but then you will not be able to change that field later on. So, if you get an entity from the DB make a change to a computed field and then call "saveChanges()" on your entity context, the field will not be altered in the DB.
Better to use EF defaults by setting the Default Value for the attribute in the EDMX editor.
It's a pain in the butt that the EDMX updater can't read the field defaults when there is a one to one mapping between the entity field and the database field.
You can update the EDMX model to change the default value for any column via the Properties window. However, Entity Framework doesn't seem to pickup DEFAULT constraints automatically. Not sure if there is a way to make it do that.

Categories

Resources