Let s say i have two classes
[Table("User")]
public class User
{
public string Name { get; set; }
public string Surname { get; set; }
}
[Table("Manager ")]
public class Manager : User
{
public int Title {get;set;}
}
and i m using entity framework 6.1.2 and table per type approach for saving entity.
Now i want to add a child (i.e. Manager) but there is a parent(i.e. User) for this child.
so what should i do
how do i insert only the child node.
You are mixing some OO principles.
A manager is a user.
This means that if you add a manager to system, you are effectively also adding a user. You can add a user to the system if it is not a manager.
Adding a manager will update both user table and manager table. Adding a user that is not a manager will only add an entry in the user table.
So in summary. All users both normal and managers will appear in the users table. But for the users that are also manager , there will also be a record in the manager table. The information that belongs to a manager is spread over 2 tables in the database. In EF because you have used inheritance you are using only a manager instance, but because it is derived from user, you get access to the user properties as well. Relational concepts and OO concepts are not the same, EF does the mapping between these distinct concepts for you, hence the name Object Relational Mapping.
Related
As Microsoft says here :
Owned entities are essentially a part of the owner and cannot exist without it, they are conceptually similar to aggregates
It means in DDD architecture (Domain Driven Design) we can use owned types (or collection of owned types ) as an entity inside an aggregation or as a value object. On the other hand, we know that ValueObject in DDD has no Identity value because of its structure and its Immutability. I want to know if I decide to use the Owned type to implement the value object how can I force it to avoid making Id in the creation table?
For example, as you see in the following picture (that Microsoft mentioned here) when we use a collection of owned types, EF makes an "Id" field in the table that no sense in Address Value Object! How to avoid it? and Is it really a correct option?
That example is from the OwnsMany scenario where it clearly explains that it needs a FK in the table to associate addresses back to their Distributor. How else would an Address record associate back to the Distriburor when loading the entities?
If a Distributor only has 0-1 address then you don't need an OwnerId on Address, the Address' Id column would serve as PK and FK back to the Distributor. EF needs a "Key" on each table to uniquely identify each row. You could possibly avoid an "Id" column by mapping a composite key, essentially:
public class Address
{
[Key, Column(0), ForeignKey("Owner")]
public int OwnerId { get; set; }
[Key, Column(1)]
public string Street { get; set; }
[Key, Column(2)]
public string City { get; set; }
public virtual Distributor Owner { get; set; }
}
A dedicated unique, and DB Generated Id column for the Address table IMO makes more sense than a large, composite key of strings and FK.
Ownership as far as the database is concerned is identical to HasOne / HasMany in the way the schema is laid out & relational rules. What differentiates OwnsMany from HasMany is how EF will allow you to access those owned entities. You cannot have a DbSet<Address>, only access Addresses through it's Distributor. It serves no real purpose except to scratch particular design pattern itches. :)
I am using Entity framework v 6.1.1 in my application.
My database has 2 tables User, Location.
User table
-----------
UserID
HomeCityId(FK -> LocationId)
CurrentCityId(FK -> LocationId)
Location table
LocationId
LocationName
Using DB First approach, I created a Entity data model for these two tables.
The generated entity class of User table
public int UserId;
public int HomeCityId;
public int CurrentCityId;
public virtual Location Location { get; set; }
public virtual Location Location1 { get; set; }
Is there a way to name these virtual properties as HomeCity and CurrentCity instead of Location and Location1?
In case of Entity Framework Database First Approach, using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. The automatically generate code enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table.
To add Data Annotations to the data model to specify validation requirements and display formatting-
changes to the auto generated class by Entity Framework is not recommended, as it is sure to get overridden whenever you update your EDMX data model, so metadata & partial class.cs files are created.
Also, note that all the files- EDMX , PartialClasses.cs and
Metadata.cs should reside at same location in your application
directory.
Please refer this tutorial:
Enhance data validation and display formatting for EF Database First with ASP.NET MVC app
On my own projects I use RavenDB. At work I use SQL Server and Entity Framework (code first).
So designing domain entities is a challenge, as I really enjoy RavenDB's ability to create an application-centric, DDD style application, that isn't tied at all to a database implementation.
At the moment I'm trying to persist an entity that has a collection of GUIDs that reference other entities in the system. For example (not the actual class, but the same concept):
public class Thing
{
public Thing()
{
this.VisibleSectionIds = new Collection<Guid>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<Guid> VisibleSectionIds { get; set; }
}
Using RavenDB, I can persist this in a few lines of code with no need to redesign the database. I can even make my collection of ids read-only.
Can people suggest ways that I could do a similar thing in EF without introducing mapping properties to other entities (this would break my DDD approach and possibly introduce N+1 issues). Can I use EF to convert my collection of GUIDs to a text datatype in the database and convert it back again?
I'm new to Entity Framework and am trying to learn how to use Code First to load entities from the database.
My model contains a user:
public class User
{
public int UserID { get; set; }
[Required]
public string Name { get; set; }
// Navigation Properties
public virtual ICollection<AuditEntry> AuditEntries { get; set; }
}
Each user can have a set of audit entries each of which contains a simple message:
public class AuditEntry
{
public int AuditEntryID { get; set; }
[Required]
public string Message { get; set; }
// Navigation Properties
public int UserID { get; set; }
public virtual User User { get; set; }
}
I have a DBContext which just exposes the two tables:
public DbSet<User> Users { get; set; }
public DbSet<AuditEntry> AuditEntries { get; set; }
What I want to do is load a list of AuditEntry objects containing the message and the related User object containing the UserID and Name properties.
List<AuditEntry> auditEntries = db.AuditEntries.ToList();
Because I have my navigation properties marked as virtual and I haven't disabled lazy loading, I get an infinitely deep object graph (each AuditEntry has a User object, which contains a list of the AuditEntries, each of which contains a User object, which contains a list of AuditEntries etc)
This is no good if I then want to serialize the object (for example to send as the result in a Web API).
I've tried turning off lazy loading (either by removing the virtual keywords from my navigation properties in the model, or by adding this.Configuration.LazyLoadingEnabled = false; to my DBContext). As expected this results in a flat list of AuditEntry objects with User set to null.
With lazy loading off, I've tried to eager load the User like so:
var auditentries = db.AuditEntries.Include(a => a.User);
but this results in the same deep / cyclic result as before.
How can I load one level deep (e.g. include the user's ID and name) without also loading back-references / following navigation properties back to the original object and creating a cycle?
After much hacking, I've come up with the following potential solution using a dynamic return type and projection in my Linq query:
public dynamic GetAuditEntries()
{
var result = from a in db.AuditEntries
select new
{
a.AuditEntryID,
a.Message,
User = new
{
a.User.UserID,
a.User.Username
}
};
return result;
}
This produces (internally) the following SQL which seems sensible:
SELECT
[Extent1].[AuditEntryID] AS [AuditEntryID],
[Extent1].[Message] AS [Message],
[Extent1].[UserID] AS [UserID],
[Extent2].[Username] AS [Username]
FROM [dbo].[AuditEntries] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[UserID]
This produces the results that I'm after, but it seems a bit long winded (especially for real life models that would be significantly more complex than my example), and I question the impact this will have on performance.
Advantages
This gives me a lot of flexibility over the exact contents of my returned object. Since I generally do most of my UI interaction / templating on the client side, I frequently find myself having to create multiple versions of my model objects. I generally need a certain granularity over which users can see which properties (e.g. I might not want to send every user's email address to low-privilege user's browser in an AJAX request)
It allows entity framework to intelligently build the query and only select the fields that I have chosen to project. For example, inside each top level AuditEntry object, I want to see User.UserID and User.Username but not User.AuditEntries.
Disadvantages
The returned type from my Web API is no longer strongly typed so I couldn't create a strongly typed MVC view based on this API. As it happens this is not a problem for my particular case.
Projecting manually in this way from a large / complex model could result in a lot of code, seems like a lot of work and has the potential to introduce errors in the API. This would have to be carefully tested.
The API method becomes tightly coupled with the structure of the model and since this is no longer fully automated based on my POCO classes, any changes made to the model would have to be reflected in the code that loads them.
Include method?
I'm still a little confused about the use of the .Include() method. I understand that this method will specify that related entities should be "eager loaded" along with the specified entity. However, since the guidance seems to be that navigation properties should be placed on both sides of a relationship and marked as virtual, the Include method seems to result in a cycle being created which has a significant negative impact on it's usefulness (especially when serializing).
In my case the "tree" would look a little like:
AuditEntry
User
AuditEntries * n
User * n
etc
I'd be very interested to hear any comments about this approach, the impact of using dynamic in this way or any other insights.
I have been reading some artices about using the RelationshipManager to gain access to the entries that have related data. It is still unclear to me what the best way to audit when an entity whose related data is added or updated.
Sample Classes:
public class Rfi
{
public Guid Id {get;set;}
public string Number {get;set;}
public virtual ICollection<Attachment> Attachments {get;set;}
}
public Class Attachment
{
public Guid Id {get;set;}
public string Name {get;set;}
public string Description {get;set;}
public string FileName {get;set;}
public string Path {get;set;}
}
Sample Mappings:
public class RfiMapping: EntityTypeConfiguration<Rfi>
{
public Rfimapping()
{
HasMany(r => r.Attachments).WithMany().Map(m =>
{
m.MapLeftKey("RfiId");
m.MapRightKey("AttachmentId");
m.ToTable("Rfi_Attachments");
});
}
}
I am using the Repository and Unit Of Work patterns. My UoW inherits from DbContext. A repository call may look like this:
public void AddAttachmentToRfi(Attachment attachment, Guid rfiId)
{
var rfi = _rfiRepository.FindById(rfiId);
rfi.Attachments.Add(attachment);
_rfiRepository.UnitOfWork.Commit();
}
Is it possible , in an overridden SaveChanges method, to figure out that an Attachment entity was added to an Rfi entity? When I traverse the, say ChangeTracker.Entries, I am not seeing its state being set to modified. Which makes sense, because I am only adding to the relationships and not the entity directly.
I know to cast my DbContext to an IObjectContextAdapter, but I am not sure what I need to do with the RelationshipManager to get the changes made to any of the relationships. I am also curious to know if I were to update an Attachment's Description property later on, if I can still see what changes were made to any related data.
My goal with this is, the user interface for the Rfi allows users to attach files (Rfi is obviously not the only entity that can have attachments). I need to show a history of everything that happens to an Rfi. This means if an attachment is added I need to audit it. If the attachment's data is updated, I need to audit those changes and show that they were updated via the Rfi interface. This may get complicated if that attachment is shared with another entity, but I will cross that road later.
As you say you are not changing any of the entities only the relationship between them.
EF will then convert this to an insert into or delete from the Rfi_Attachments table.
One way to audit this is to add a database trigger that writes an entry to a log table, each time an entry is added or deleted.