Entity Framework POCO - Navigation Property does not refresh - entity-framework

I have an issue with poco classes in EF 4.
I have an Order entity wich contains a foreign key to a Customer entity.
So, the Order class has a navigation property of type Customer.
It's look like this :
public class Order
{
public virtual int Id { get; set; }
public virtual CustomerId { get; set; }
public virtual Customer customer { get; set;}
…
}
When I load an order, the navigation property customer is correct, but if the CustomerId property changes, the navigation property is not refresh with the new customer.
If I call the DetectChanges() method on the EF context, the navigation property is then refreshed.
I've read that with all properties marked as virtual, the relationship synchronisation is automatic, but it's not the case here.
Where did I go wrong ?
Thanks for any help

It means that for some reason proxy was not created for you entity. Take a look at this blog post - http://blogs.msdn.com/b/adonet/archive/2009/12/22/poco-proxies-part-1.aspx. Here are the requirements for creating proxies: http://msdn.microsoft.com/en-us/library/vstudio/dd468057(v=vs.100).aspx. Proxy creation must not be disabled.

Related

Entity Framework - Database generated identity is not populated after save if it is not the key of the entity

I have a model like
public class MyEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public int Id { get; set; } // Id
[Required]
[Key]
public System.Guid GUID { get; set; }
}
The GUID property is the PK by design, but I have a db generated Id property that I use within my code to determine if the object is a new object that hasn't been saved yet.
When I save this object with Entity Framework, the Id property does not get back populated as normally happens for database generated properties (although usually these are keys). I have to query the DB for the object and grab the ID manually. It seems EF only back populates Key properties on SaveChanges.
Is there any way to get EF to automatically populate the Id property here? Setting it as the Key is not an option, I have dozens of tables that are FK'd to the GUID property and for good reason.
EDIT: I have discovered that the package https://entityframework-extensions.net/ is handling my save changes. If I use the standard EF savechanges it works, but not with the extensions version.
Disclaimer: I'm the owner of Entity Framework Extensions
It was indeed an issue in our library. This scenario was not yet supported for EF6.
However, starting from the v4.0.50, it should now work as expected.

Entity Framework (C# ASP.NET) - Association Entity without Tracking in Non-Dependent Entity

I have two Model classes to be created using Entity Framework: Skill and Activity. The following are the definitions of each:
Skill.cs
public class Skill
{
public int Id { get; set; }
public String Name { get; set; }
}
Activity.cs
public class Activity
{
public int Id { get; set; }
public String Name { get; set; }
public virtual List<Skill> RequiredSkills { get; set; }
}
Ideally, in the database, I'd want the Activity to be linked via foreign key to a association entity (e.g. SkillActivityAssoc) and the Skill not to have to do anything with it. I don't need to track which activities need a certain skill. I just need to track what skills are needed for each activity thus explaining why I don't have a List in the Skill class. I hope that made sense.
My question is: Is this the right way to go about doing this? When I update the RequiredSkills property of Activity via:
activity.RequiredSkills = someInstanceOfRequiredSkillsList;
dbcontext.Entry(activity).State = EntityState.modified;
dbcontext.SaveChanges();
.., it doesn't work. I'm already speculating that it's because I'm not able to update the association entity. Moreover, my current implementation has a virtual List<Activity> property in the Skill class which I want to get rid of. How do I go about changing my model design and how do I update RequiredSkills accordingly?
Thank you in advance!
virtual is for lazy loading and track changes in EF. You can read more about it here: Understanding code first virtual properties. You should also read MSDN documentation about loading entities in EF: https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx
Since you want to have more than one Skills in each Activity and each Skills can be in more than one Activity as well, you have a many-to-many relantionship. Please read this example: How to create a many-to-many mapping in Entity Framework? and this http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx

add several references to the same record in navigation property

In my EF 6 Model First application, I have an entity with a many-to-many navigation property to another entity. In the first entity, I need to add several references to the same record in navigation property.
The first entity is a “saleslistItem” and the second entity is “warehouseItem”. Normally there will be a one-to-one relationship here, but exceptionally there will be some bundles where one “saleslistItem” contains several “warehouseItems”. “WarehouseItem” can also be included in several “salesListItems”. At the end of the project, my customer says, testing it, that “saleslistItem” must be able to consist of several “WarehouseItems” of the same kind (like two boxes of smoked ham).
These data is used several places in my code. (ie. doing a sale removes items from the warehouse) If I could just add several the same reference, my code would work without any modifications. But in the implementation of the navigation property the “hashtable”-collection is used, and this collection requires unique entries. Is there a workaround here? Performance is irrelevant as the data amount is small.
If there are no such workaround, is it possible to store values together with the instance of navigation property? Maybe it is implemented as a field in the join-table???
Any other suggestions?
Need a solution so the customer pays the last part of the bill!
So you currently have a 1:1 from SalesListItem toWarehouseItemvia a ForeignKey inSalesListItem`? Sounds like you need:
public class SalesListItem
{
public virutal ICollection<SalesListWarehouseItem> WareHouseItems { get; set; }
}
public class SalesListWarehouseItem
{
public virtual SalesListItem Parent{ get; set; }
public virtual WarehouseItem WarehouseItem { get; set; }
public int Quantity { get; set; } // maybe double?
}

Exposing only aggregate roots from a DBContext

I am a new bie to DDD. In our DDD project ,we have a requirement that our DBContext should only expose AggregateRoots.. Assuming that our DbContext is as shown below
public class ClassContext : DbContext
{
public DbSet<Class> Classes{ get; set; }
public DbSet<Students> Students{ get; set; }
}
and Class is the aggregate root . Is the following implementation the right way
public class ClassContext : DbContext
{
public DbSet<Class> Classes{ get; set; }
private DbSet<Students> Students{ get; set; }
}
Any comment is appreciated
It's certainly useful to think about aggregate roots in your application, but don't try to apply DDD concepts to an Entity Framework class model.
An Entity Framework class model is not a domain model. It's a data access layer. Any considerations regarding including or hiding entities and/or navigation properties should be motivated by facilitating smooth data access and nothing more.
It's highly unlikely that you're always going to read/create/update/delete students through classes only. That would make unnecessary clunky code. And who says that students will always be in a class?
But maybe this isn't the best example of an aggregate. A Student doesn't have an identifying relationship with a Class, because next time he'll be in another class. It would be different with the classic Order-OrderLine relationship. I can imagine that in that case you might only expose a DbSet<Order>.
So just expose the DbSet<Students> as public class.
I don't think the private declaration for Students is needed.
Presumably the Class object contains something like
public virtual List<Student> Students { get; set; }
so, given the requirement that you are only exposing aggregate roots,your code to find a student will always need to find a class and pull the student from it.

EF code-first foreign key

I have a class Question
CompareItems store CurrentQuestion-to-OtherQuestion compare information.
public class Question
{
public virtual ICollection<QuestionMark> CompareItems { get; set; }
}
public class QuestionMark
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int Question { get; set; } //Store ID of OtherQuestion
public decimal Mark { get; set; }
}
When I delete some question A I need that all QuestionMark where QuestionMark.Question == A.Id also deleted, because it's no need to have compare information if question not exist. How it possible to do that without making QuestionMark.Question an entity? Maybe EF have some rule in Fluent-API to set that QuestionMark.Question is foreign key on Question entity?
I don't wont to make QuestionMark.Question as entity because it will need to change current solution lot - is a first. Also, question is a quite heavy entity, and to load it multiple time to assign value or delete or something else will be press on performance
I think it's possible to change app to use Entities instead of id, because EF use lazy loading by default and it will not caused performance problems. And I think that using just id instead of entity possible with some fluent API settings or attribute.
If you do not want to make a navigational property Question in QuestionMark class then you need to manually create a foreign key with "cascade delete". Then when every a question is deleted the database will delete the related QuestionMark records.
However this approach has a problem with EF. Because EF does not know there is a "cascade delete" relationship among these entities. So there can be inconsistencies within the locally tracked entities in EF.
You have not given a reason as to why you do not want to map the relationship in EF but I highly advice you against it.