Self Tracking entities and the mysterious ChangeTracker_ChangeTrackingEnabled datatable column - entity-framework-4

I'm using Self Tracking Entities that implements IObjectWithChangeTracker with the last Entity Framework RC available as a Nuget. The target database is PostgreSQL. I'm also using Code First fluent API to construct the model and LINQ to Entity for querying the database.
To my surpise, a simple SELECT query on the entity generates a SQL query with a mysterious column ChangeTracker_ChangeTrackingEnabled that does not exist in the datatable ! I do not understand this behavior as it seems to me that the EntityTypeConfiguration derived class maps the entity properties to the datatable columns in its constructor.
Is there a way to disable this behavior or at least tell which column should be mapped by the change tracker ?
For that purpose, Context.Configuration.AutoDetectChangesEnabled = false or calling IsConcurrencyToken() mapping in the EntityTypeConfiguration derived object does not help.
Any help appreciated.
TIA.

You must inform EF about every public property you want to avoid in mapping by either marking property with NotMapped attribute or by using Ignore in fluent API.
Btw. as I know STEs are not designed to be used with code first or DbContext API.

Related

How does Breeze handle database column defaults?

I can't find any info about this in the documentation, so I will ask here. How does breeze handle database column defaults? I have required columns in my database, but there are also default static values supplied for these in the database column definitions. Normally, I can insert null into these columns, and the new records will get the default. However, breeze doesn't seem to be aware of database column defaults, and the entities that have null in these columns fail validation on saving.
Thanks,
Mathias
Try editing the edmx xml by adding StoreGeneratedPattern = "Computed" attribute to the column with default value in the DB.
Edit:
Actually, before doing editing the xml, try setting the StoreGeneratedPattern property to Computed in the model editor itself.
Update:
This was fixed in Breeze 1.4.6 ( or later), available now.
Original Post:
There is currently in a bug in Breeze that should be fixed in the next release, out in about week. When this fix gets in then breeze will honor any defaultValues it finds in the EntityFramework data model.
One problem though is while it is easy to get 'defaultValues' into a Model First Entity Framework model via the properties editor, it's actually difficult to get it into a Code First EF model, unless you use fluent configuration. Unfortunately, EF ignores the [DefaultValue] attribute when constructing Code First model metadata.
One workaround that you can use now is to poke the 'defaultValue' directly onto any dataProperty. Something like:
var customerType = myEntityManager.metadataStore.getEntityType("Customer");
var fooProperty = customerType.getProperty("foo");
fooProperty.defaultValue = 123;

How to prevent lazy loading of entities that were already manually loaded when navigating a property in EntityFramework

Background:
I am using EF4 and ObjectContext. To optimze retrieval of complex object hierarchies, I manually execute database queries and then use ObjectContext.Translatey<T>(DataReader, entitySetName, mergeOptions.AppendOnly) to turn data rows into entities. I then attach the entities to the ObjectContext with Attach method. This also fixes relations between entities.
The problem:
After everything is loaded and set up I try to navigate from parent entity to a child entity (for example Parent.Childs.First()), but EF hits the database to load the kids, even though all the child entities are already present in the ObjectContext and EntitySet. It looks like the reason for this is that parent.Childs.IsLoaded is set to false which makes EF think that it still needs to load the relation.
Question:
How can I tell EF that EntitySet has already been loaded?
Is there a supported way to set RelatedEnd.IsLoaded to true. I wouldn't like to mess with the calling the RelatedEnd.SetIsLoaded internal method.
I found a smilar question here but it relates to DbContext and has no satifying answer ;-)
Matra
It looks like this was implemented in this change:
http://entityframework.codeplex.com/workitem/269
You can now iterate through your entities and tell them that their child collections are already loaded:
foreach (var entity in loadedEntities)
context.Entry(entity).Collection(a => a.SomeChildCollection).IsLoaded = true;
This will prevent entities in SomeChildCollection from being loaded when they are accessed from entity.
I'm not exactly sure what version of EF this appeared in but I'm guessing 6.0.0.
The only way to solve this is to turn off lazy loading. The question you have found on MSDN asks about DbContext but the answer mentions that there is no way to change the value in underlying libraries - ObjectContext API (= EF4 in your case) is the underlying library. Even in .NET 4.5 (EF5) setting IsLoaded is still not available on public API.

Do Partially Defined Entiy Classes in code-first approach work?

I am using the code-first approach in Entity Framework 4.0. I have defined an entity class called 'Product' which contains these properties only - ProductId, ProductName and ProductDescription.
However, the table in database called 'Products' has additional columns like ProductAge, ProductWeight, ProductVolume and IsActive. Will updating/inserting using Entity Framework code-first approach still work with a partially defined entity class?
Trivial issue would be inserts to the table if the unmapped columns are not nullable. Otherwise inserts will work fine. Assuming you are not going to recreate the database from your code first model, it should work.

Entity Framework, Oracle, DevArt, Context#ExecuteStoreQuery: System.Int32 constructed as System.Double?

I have an Entity-class having a Property of type Int32: on generating DDL using DevArt for ORACLE a NUMBER(10) column is generated. Reading and writing instances works flawlessly.
However, on fetching instances of this Entity-class sending a custom query to ExecuteStoreQuery on the ObjectContext this Property seems to be returned as System.Double, as such constructing the instances fails.
Can I hint DevArt to construct System.Int32?
Thank you.
Bart
The reason is the fact that OracleDataReader, which is used in the ExecuteStoreQuery method, has type mapping different from the one used in the Entity Framework provider.
I recommend you to use NumberMappings, I suppose you will need to map Number(10) to Int32: Number Mappings=((NUMBER,10,10,System.Int32). These changes should be persisted to the model connection string (they are duplicating the default EF mapping rules, it is necessary for the OracleDataReader from ExecuteStoreQuery).
Please let us know if the problem persists.

Can you map the results of a manual SQL query to objects in Entity Framework?

In LINQ, you can write a manual SQL query, take the results from it and have LINQ "map" those into the appropriate properties of your Model classes (or at least, I'm pretty sure I read you can do that).
Is it possible to do something like that in Entity Framework?
I have an web app that's using EF, and it's CPU usage is ridiculously high compared to the traffic it has, and profiling it in my machine, all that time is (predictably) spent in the DB functions, and the largest portion of that time (> 85%) is spent by EF "generating" SQL and doing stuff before actually executing a query.
So my reasoning is that I can just go in and hardcode the SQL queries, but still use my populated Model properties in my view.
Is this possible? If so, how would I do it?
Thanks!
Daniel
So what you want to do is hydrate an object from an IDataReader? It's pretty easy to write code to do this (hint: reflection! or you can get fancy and use a member initialization expression) or you can Google for myriad existing implementations on the Internet.
You can do this within EF using ObjectContext.ExecuteStoreQuery<T> or ObjectContext.Translate<T> if you already have a DbDataReader.
1 ObjectContext.SqlQuery in EF 4.0
As said #Jason, you can :
IEnumerable<MiniClient> results =
myContext.SqlQuery<MiniClient>("select name,company from client");
Reference : https://msdn.microsoft.com/en-us/library/dd487208.aspx
DbContext.Database.SqlQuery, in EF 4.1+
In Entity Framework 4.1+, DbContext is preferable to use to ObjectContext, so you'd better use :
DbContext myContext= new DbContext();
IEnumerable<MiniClient> results =
myContext.SqlQuery<MiniClient>("select name,company from client");
Reference : https://msdn.microsoft.com/en-us/library/jj592907(v=vs.113).aspx
dynamic and anonymous class
Too lazy to create a projection class like MiniClient ?
So you should use anonymous type and dynamic keyword :
IEnumerable<dynamic> results =
myContext.Clients.Select( c => new {Name = c.Name, Firstname = c.Firstname});
Note : In all the samples MiniClient is not an entity of the DbContext.
(=not a DbSet<T> property)

Resources