-
Notifications
You must be signed in to change notification settings - Fork 226
Settings.AddOwnedEntityMappings
Groups columns that share a prefix into an EF Core owned entity, so BillingAddress_Street and its neighbours become customer.BillingAddress.Street.
| Type | Action<List<OwnedEntityMapping>> |
| Default | Adds nothing |
| Applies to | EF Core only. EF 6 complex types are not generated |
| Databases | All |
In Database.tt? |
Yes, with commented-out examples |
Databases often flatten a value object across several columns:
CREATE TABLE dbo.Customer
(
CustomerId int NOT NULL IDENTITY(1, 1),
BillingAddress_Street nvarchar(100) NOT NULL,
BillingAddress_City nvarchar(60) NOT NULL,
BillingAddress_Postcode nvarchar(10) NOT NULL,
ShippingAddress_Street nvarchar(100) NULL,
ShippingAddress_City nvarchar(60) NULL,
ShippingAddress_Postcode nvarchar(10) NULL
);Reverse engineered literally, that is a Customer class with six string properties and no Address type
anywhere. EF Core's answer is an owned entity: a type with no identity of its own, whose properties live
in the owner's table. This setting is how you declare one.
You add a mapping per prefix. The generator then hides the prefixed columns from the POCO, generates an
Address class, adds one property of that type, and emits the matching builder.OwnsOne(...) configuration.
Settings.AddOwnedEntityMappings = delegate(List<OwnedEntityMapping> mappings)
{
mappings.Add(new OwnedEntityMapping
{
Schema = Settings.DefaultSchema, // or "*" to match any schema
Table = "Customer", // or "*" to match any table
ColumnPrefix = "BillingAddress_", // the columns to group
PropertyName = "BillingAddress", // the property on Customer
PropertyType = "Address" // the class to generate
});
mappings.Add(new OwnedEntityMapping
{
Schema = Settings.DefaultSchema,
Table = "Customer",
ColumnPrefix = "ShippingAddress_",
PropertyName = "ShippingAddress",
PropertyType = "Address" // the same class, used twice
});
};Those five fields are all OwnedEntityMapping has. Full before-and-after output, including the generated
Address class and the OwnsOne block, is on Owned Entities.
- Value objects flattened into columns. Addresses, money amounts, date ranges, audit stamps - any group of columns that is conceptually one thing.
-
The same shape on several tables. Use
Table = "*"and the generator produces oneAddressclass shared by all of them. - Cleaning up a wide table. Twenty columns become five properties, three of them owned entities.
Leave it alone if the columns only look related. An owned entity is a modelling claim, and EF will treat the group as a single value from then on.
One class per distinct PropertyType, deduplicated across mappings. Two mappings naming Address
generate one Address class. If the two column groups are not the same shape, the first mapping wins and the
second one's extra columns are lost. Give them different type names unless the shapes match exactly.
Nullability is decided by the winning mapping too. With BillingAddress_Postcode NOT NULL and
ShippingAddress_Postcode NULL, the shared Address.Postcode takes whichever was added first. Read the
generated class rather than assuming.
The prefix is matched case-insensitively and stripped, trailing separator included, so
BillingAddress_Street becomes Address.Street and not Address.BillingAddress_Street.
EF Core only. On EF 6 the mappings are collected and then ignored. EF 6's nearest equivalent is a complex type, which this generator does not produce.
Write your own class outside the generated folder if you would rather hand-write Address. The generator
writes one file per unique PropertyType and will overwrite yours if it lands in the same place.
This is not the JSON column feature. ExcludePropertyConfiguration belongs to JsonColumnMapping, not
here. The two produce similar-looking nested types and are configured separately - see
JSON column support.
- Owned Entities - the full walkthrough, with generated before and after
- Settings.OwnedEntityFolder - where the generated classes go
- JSON column support - the other route to a nested type
- Settings Reference
- Settings A-Z - every setting, with a page each
- Common Settings Types Explained
- Settings Callbacks
- Settings runtime values and helpers
- Filtering
- Full Control Over the Generated Code
- Enum Generation from Table Data
- Owned Entities
- JSON column support
- Global Query Filters
- Extended Property Names Feature
- Partial Properties
- File-Scoped Namespaces
- Data Annotations
- Spatial Types
- HierarchyId
- RowVersion and TimeStamp columns
- Lazy Loading
- Stored proc result sets
- Custom File-Based Templates
- Extra entities via partial classes
- INotifyPropertyChanged
- Syntax colour for T4