EF Code First - Models , when should properties be instantiated in constructor? - entity-framework

I was wondering if there is a good explanation somewhere as to when a Property will need to be instantiated
in a model class constructor and when it is not necessary?
Docu on the MS EF site is good and covers a lot of related topics
Relationships and Navigation Properties - http://msdn.microsoft.com/en-us/data/jj713564
Configuring relationships with API http://msdn.microsoft.com/en-us/data/jj591620%20%22Configuring%20relationships%20with%20API
Entity Framework class library http://msdn.microsoft.com/en-us/library/hh289362%28v=vs.103%29.aspx
and im also part way through reading the Book Programming Entity Framework - Code First By Julia Lerman
I would like to better understand when a property needs to be instantiated in the Model constructor.
I see Samples in MS documentation and in the Book with and without newed up properties in the Model constructor.
There is most likely a good reason why some solutions use a constructor with newed Up objects and others not.
Seems like Virtual ICollection has the new List<> and complex type has new RefObj.
But simple virtual navigation property of type ModelObject are Ok without new.
Can I stick to a pattern without knowing the internals of each convention class. Or is there another topic I should be reading?

You never need to instantiate a property in the models constructor for EF to work, but it make it more convenient.
For example, If you had a class Order and it has children of Order Detail, and you wanted to add a new Order to your database.
Without initializing OrderDetails
var order = new Order();
order.OrderDetails.Add(new OrderDetail()); // this would error because OrderDetails is null
One option could be to call order.OrderDetails = new List();
before you use Add(), but then you would need to have that code repeated everywhere you wanted to use Add(). Instead you can put that code in the constructor, and then OrderDetails will be ready to use with all newly created Orders.

Related

Entity Framework DbSet<?> - Column names of database unknown at compile time

So I have run into a situation where I need to use the Entity Framework (DbContext) with databases whose columns are not known at compile time. Basically I don't have the luxury of hard coding a customTable class to put into the DbSet.
The only thing I can think of for solving this issue is using Reflection.Emit to create a customTable class at run-time based on information I glean by interrogating a database.
I was not able to find any information of solving this issue, but I am very new to working with the Entity Framework so maybe a solution would be more obvious to someone more experienced.
I feel like there should be a cleaner way than using Reflection.Emit to dynamically create a class to feed DbSet.
If I am way off base for the intended use of the Entity Framework that information would be useful as well.
Hi I'm investigating this problem too and I have found what seems like the solution.
http://romiller.com/2012/03/26/dynamically-building-a-model-with-code-first/
tells you how to make a DbContext into which you add a new DbSet using a type as a parameter. You can create this type using the Dynamic Linq Library:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
It has a method called CreateClass which will allow you to dynamically build a POCO class definition from a list of field names and load it, you can then create a DbSet using the new type you have created.
You can then get a non-generic DbSet from your updated DbContext using
db.Set(type)
where 'type' is a variable holding your new type. This can be worked on using the linq predicates in the dynamic linq library.
Incidentally, my application is for a CMS where new modules can add fields to the core data table for the CMS, and I don't want to use DI as its too inflexible as no given module will be able to provide a type which has all the fields it needs and all the other unknown modules might also need.
James

Entity Framework, Link tables and mapping multiple tables to a single entity

I have an Entity called "Product", this entity, through table mapping, merges 6 tables that have a 1 to 1..0 relationship with "Products". This all works wonderfully. There is another property I want to add to "Products", which is sBBR_rate, this value is not in a table that has a direct 1 to 1..0 relationship, it is related through a link table as below:
When I import the two tables into the EDM, I can't see a way in the "Mapping Details" of
"Product" to reference the sBBR_rate. I can reference RatesLink and link that to the "Products" primary key, however, I cannot reference the BBR table.
The methods I can think of to work "around" this is are as follows:
Create a view, reference the view in the EDM.
Create an SP and use a function import to retrieve the BBR when it is required.
Create a "Rates" entity in the EDM that can then draw down the sBBR_rate into it. Navigate to the Products BBR through Product.Rates.sBBR_rate.
Is there a better way I can do this that doesn't feel so much like a fudge? Perhaps by directly editing the XML of the Mapping or Conceptual layers of the EDM?
Thanks for your input.
Because the multiplicities on the Product -> RatesLink and RatesLink -> BBR relationships are 0 to 1, you should be able to access the sBBR_rate from a Product instance like this:
myProductInstance.RatesLink.BBR.sBBR_rate
I can see on the EDM screenshot that RatesLink has a Product and BBR property, which would indicate this should be available - is it?
On a side note, if it makes sense for the sBBR_rate property to commonly be accessed directly from Product, you might want to follow the law of demeter and create a property on Product which returns it directly.
The model we are using is to extend entities by using partial classes which we've found useful so we can get additional properties in the autogenerated classes (we are using a POCO T4 template to autogen but I believe this would work just as well with the default entity object generation).
So we would have
//.. this one is from the T4 template
public partial class Product
{
//.. all the autogenerated methods
}
and in a separate file that isn't autogened
//.. now in a separate file created by me
public partial class Product
{
//.. my custom properties and methods to make the entities more usable
public string BBRRate
{
get {return this.RatesLink.BBR.sBBR_rate; }
}
}
This means that I can just do
myProduct.BBRRte
I know there are other ways to do this by amending the edmx file but this one we found easy to implement. You just need to watch performance because you are potentially loading extra data. Also we did this with LazyLoading turned on but with more work you wouldn't have to
We also experimented with hooking into the ObjectMaterialized event in the ObjectContext class to preload some of these properties. Using a custom interface i.e. IMaterialisable we could check if the object was of that type then call a method (Materialise) to prepopulate some of the properties. This seems like a good idea but we didn't widely use it - it was easy to load up too much stuff. If you do the load on the properties in the partial classes then it becomes more efficient. Just my experience.
Anyway - as always an interesting question and good luck again with your dev.
EDIT
There is a rule that everything in the store layer must be represented some way in your conceptual layer. Therefore removing the tables from the conceptual layer but bring through some of the properties I don't think will work in it's gross form. Therefore I can think of two further options
Create a View on the database and bring that in as you have already mentioned. TBH this is what I would do.
Use the DefiningQuery element directly in your xml (the store layer) and map the query through to a custom entity of your exact design. Julie Lerman describes this as the ultimate escape hatch for Entity Framework.
Remember though - if you manual amend the XML in point 2 then you lose the ability to automatically update the module through the IDE
I ended up creating a view and then linking this view in the EDM, this worked a treat.

Zend Quickstart Tutorial Conceptual Problem

I am trying to learn zend framework, and managed to get through the whole quickstart tutorial they have. However, there is something that I simply can not understand, and was hoping somebody can help me with.
In the tutorial, you create a db-table class, a mapper, and a model. I read the documentation, and understand the purpose of the db-table class (define table, relations, create/fetch rows). When you query the db-table class, you'll get an object of class db-table-row, which you can use to manipulate a specific record in the db.
However, I can not understand why the tutorial would have me create a mapper and a model, nor the reason for defining getter/setter methods in the model (shouldn't those be provided by db-table-row?)
Even in the controller, they created an object from the model class and the mapper class, then they completely ignored the model object, and just used the mapper object.
Is there any need at all to have those 3 classes? what different purpose does each fulfill? As far as I can see, all I need is the db-table class, am I right?
When you query the db-table class, you'll get an object of class
db-table-row
No you get db-table-rowset instead which is collection of row .
secondly
you don't even need db-table class
$dbTable = new Zend_Db_Table('tableName');
But since db-table class allow you to define relationship between other tables inside it (business logic) hence became important .
db-table-row became important when the entity is important for e.g User Table . Inside your custom db-table-row for user you can add method getTopics(); which return rowset for all the topics created by theat user hence fruther helping with business logic.

Table per hierarchy inheritance with POCO entities in Entity Framework 4

Our organization is looking to standardize on Entity Framework once v4 comes out. As a result, I am looking at what it would take to migrate our application that uses NHibernate for persistence to EF4 using POCO support. In a couple of places we use single table inheritance (also known as Table Per Hierarchy). I have been unable to get it to work using the following.
Payment (base class [should be abstract but having trouble there as well])
CreditCardPayment (concrete implementation)
ACHPayment (concrete implementation)
CheckPayment (concrete implementation)
Right now, I am mapping them with only the base class properties. All of these classes are in the same namespace. They have a discrimimator that is called PaymentTypeId in the database, so the Payment mapping has a condition of "When PaymentTypeId = 0". Each of the subclasses have the same condition with different values (i.e. CreditCardPayment = 1, etc.).
When I try to load each a list of all payments using DataContext.Payments.ToList() (DataContext inherits from ObjectContext) I am getting the following exception:
"Object mapping could not be found for Type with identity 'DataLayer.DataModel.CreditCardPayment'."
I can't figure out what this means, as the POCO CreditCardPayment class lives in the same namespace as the POCO Payment class does (in fact in the same file).
What am I missing?
This is complaining not about database mapping, but model to CLR mapping.
The EF can't for some reason find your CreditCardPayment class.
Now one possible reason is that you haven't loaded the metadata for it yet.
For example if you have this:
Assembly 1:
- Payment
Assembly 2 references Assembly 1:
- CreditCardPayment extends Payment
Then when you query the EF doesn't know where CreditCardPayment lives.
The way to get around this is with LoadAssembly i.e:
using (DataContext ctx = new DataContext())
{
ctx.MetadataWorkspace.LoadFromAssembly(typeof(CreditCardPayment).Assembly);
// now do your query.
}
You need to tell to LoadFromAssembly every assembly that isn't directly reference by your DataContext class.
Note: typeof(Payment).Assembly is directly referenced because of the IQueryable<Payment> Payments property.
Hope this helps
Alex
Microsoft.
What I didn't represent before (I didn't think it relevant, but it was). Was that CreditCardPayment inherited from an intermediary class named "CreditPayment" and ACHPayment inherited from CashPayment. CreditCardPayment and CashPayment live in the same namespace and file, but were not represented in the EF mapping. Once I added those within the mapping file, everything worked ok.
So, even thought EF does not ever map to one of those types directly, it seems to need to know about them, because it changes the basetype of the CreditCardPayment classes et al. Thank you for your help on this.

Inheritance problems with Entity Framework (table per type)

For part of the project I'm currently working on, I have a set of four tables for syndicatable actions. One table is the abstract base for the other three, and each table is represented in my EF model like so:
EF Model -- Actions http://chris.charabaruk.com/system/files/images/EF+Model+Actions.png
There are two problems that I'm currently facing with this, however. The first problem is that Actor (a reference to a User) and Subject (a reference to an entity of the class associated with each type of action) are null in my subclasses, despite the associated database columns holding valid keys to rows in their associated tables. While I can get the keys via ActorReference and SubjectReference this of course requires setting up a new EF context and querying it for the referenced objects (as FooReference.Value is also null).
The second problem is that the reciprocal end of the relationship between the concrete action classes and their related entity classes always turn up nothing. For example, Task.RelatedActions, which should give me all TaskAction objects where Subject refers to the particular task object on which RelatedActions is called, is entirely devoid of objects. Again, valid rows exist in the database, Entity Framework just isn't putting them in objects and handing them to me.
Anyone know what it is I'm doing wrong, and what I should do to make it work?
Update: Seems that none of the relationship properties are working in my entity model any more, at all. WTF...
I think the issue you are experiencing here is that by default the EF does not automatically load related entities. If you load an entity, the collection or reference to related entities will be empty unless you do one of the following things:
1) Use eager loading in order to retrieve your main entity and your related entity in a single query. To do this, modify your query by adding a call to the Include method. In your sample above, you might use the following query:
from a in context.Actions.Include("Actor") select a
This would retrieve each of the actions with the related Actor method.
2) Use explicit lazy loading to retrieve the related entity when you need it:
action1.ActorReference.Load()
In the version of the EF which will ship with .Net 4.0, you will also have the following additional option:
3) Turn on implicit lazy loading so that related entities will automatically be retrieved when you reference the navigation property.
Danny