entity framework column name to property mapping dbentry

c# entity-framework entity-framework-core

Question

I'm trying to map entity properties to database column names while saving entities in DbContext, but I can't figure how to do it in EF7.

After generating database schema with migrations, column names are not always the same as properties names in object. For example, below object schema:

public class Document
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public User Author { get; set; }
}

would have Id, Name and AuthorId columns in database. Next when I'm iterating over EntityEntry properties, it contains Id, Name and AthorId columns. I can easily map Id and Name.
Thing I'm looking for is how to figure out that "AuthorId" in EntityEntry is mapped to Author field in Document?



Backround: I'm implementing universal object version history mechanism, which would get modified columns from EntityEntries (from ChangeTracker in SaveChanges() in DbContext) and save proper columns and it new values. Next, when restoring objects it should be able to map these changes to proper entity fields.

I have found similar question for EF6 Where does Entity Framework store the mapping between property names and the columns it selects in SQL? but it is quite complicated and uses classes specific to EF6.

Popular Answer

As per my comment, the Author field is not a simple object/struct (IE: DateTime, Enum, etc) nor a primitive (IE: int, string, etc). As such, it is a Navigation Property and only the ID of the object is stored. This ID then allows you to navigate to the row in another table that stores the complex data of the Author object.

As such, you would want a DbContext and DbSets as such:

public class Document {
    public int Id { get; set; } // No need for [Key] ID is auto detected
    public string Name { get; set; }

    // Foreign Keys
    public int AuthorId { get; set; } // Can use "int?" if you want to allow it to be nullable
    public User Author { get; set; }
}

public class Author {
    public int Id { get; set; }
    public string Name { get; set; }
}

public class BookContext : DbContext {
    public DbSet<Author> Authors { get; set; }
    public DbSet<Document> Documents { get; set; }
}

This will produce tables:

Document: Id (int), Name (nvarchar), AuthorId (int) with FK to Author table
Author:   Id (int), Name (nvarchar)

When querying the DB:

var books = BookContext.Documents // Access documents table
                 .Include(q => q.Author) // Ensure that the author's properties are loaded, not just the ID
                 .Where(q => q.Name.Contains("SomeText")) // Search for documents with a name matching this text


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why