Her*_*man 107 c# entity-framework-core
在EF6中,我们通常能够使用这种方式配置实体.
public class AccountMap : EntityTypeConfiguration<Account>
{
public AccountMap()
{
ToTable("Account");
HasKey(a => a.Id);
Property(a => a.Username).HasMaxLength(50);
Property(a => a.Email).HasMaxLength(255);
Property(a => a.Name).HasMaxLength(255);
}
}
Run Code Online (Sandbox Code Playgroud)
我们如何在EF Core中做,因为当我继承EntityTypeConfiguration类时无法找到该类.
我从GitHub下载EF Core原始源代码,我找不到它.有人可以帮忙吗?
Krz*_*cki 150
从EF Core 2.0开始IEntityTypeConfiguration<TEntity>.你可以像这样使用它:
class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.HasKey(c => c.AlternateKey);
builder.Property(c => c.Name).HasMaxLength(200);
}
}
...
// OnModelCreating
builder.ApplyConfiguration(new CustomerConfiguration());
Run Code Online (Sandbox Code Playgroud)
有关此内容以及2.0中引入的其他新功能的更多信息,请参见此处.
dev*_*tal 51
您可以通过一些简单的其他类型实现此目的:
internal static class ModelBuilderExtensions
{
public static void AddConfiguration<TEntity>(
this ModelBuilder modelBuilder,
DbEntityConfiguration<TEntity> entityConfiguration) where TEntity : class
{
modelBuilder.Entity<TEntity>(entityConfiguration.Configure);
}
}
internal abstract class DbEntityConfiguration<TEntity> where TEntity : class
{
public abstract void Configure(EntityTypeBuilder<TEntity> entity);
}
Run Code Online (Sandbox Code Playgroud)
用法:
internal class UserConfiguration : DbEntityConfiguration<UserDto>
{
public override void Configure(EntityTypeBuilder<UserDto> entity)
{
entity.ToTable("User");
entity.HasKey(c => c.Id);
entity.Property(c => c.Username).HasMaxLength(255).IsRequired();
// etc.
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.AddConfiguration(new UserConfiguration());
}
Run Code Online (Sandbox Code Playgroud)
Avi*_*rry 28
在EF7中,您在正在实现的DbContext类上重写OnModelCreating.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Account>()
.ForRelational(builder => builder.Table("Account"))
.Property(value => value.Username).MaxLength(50)
.Property(value => value.Email).MaxLength(255)
.Property(value => value.Name).MaxLength(255);
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ohn 21
这是使用当前最新的测试版8.试试这个:
public class AccountMap
{
public AccountMap(EntityTypeBuilder<Account> entityBuilder)
{
entityBuilder.HasKey(x => x.AccountId);
entityBuilder.Property(x => x.AccountId).IsRequired();
entityBuilder.Property(x => x.Username).IsRequired().HasMaxLength(50);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的DbContext中:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
new AccountMap(modelBuilder.Entity<Account>());
}
Run Code Online (Sandbox Code Playgroud)
小智 16
从 EF Core 2.2 开始,您可以在类中的 OnModelCreating 方法中的一行中添加所有配置(类,实现了 IEntityTypeConfiguration 接口),该类继承自 DbContext 类
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//this will apply configs from separate classes which implemented IEntityTypeConfiguration<T>
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
Run Code Online (Sandbox Code Playgroud)
而且,正如前面的回答中提到的,从 EF Core 2.0 开始,您可以实现接口 IEntityTypeConfiguration,在 Configure 方法中使用 FluentAPI 设置映射配置。
public class QuestionAnswerConfig : IEntityTypeConfiguration<QuestionAnswer>
{
public void Configure(EntityTypeBuilder<QuestionAnswer> builder)
{
builder
.HasKey(bc => new { bc.QuestionId, bc.AnswerId });
builder
.HasOne(bc => bc.Question)
.WithMany(b => b.QuestionAnswers)
.HasForeignKey(bc => bc.QuestionId);
builder
.HasOne(bc => bc.Answer)
.WithMany(c => c.QuestionAnswers)
.HasForeignKey(bc => bc.AnswerId);
}
}
Run Code Online (Sandbox Code Playgroud)
Coc*_*lla 12
您可以使用反射来完成与它们在EF6中的工作方式非常相似的操作,并为每个实体使用单独的映射类.这适用于RC1决赛:
首先,为您的映射类型创建一个接口:
public interface IEntityTypeConfiguration<TEntityType> where TEntityType : class
{
void Map(EntityTypeBuilder<TEntityType> builder);
}
Run Code Online (Sandbox Code Playgroud)
然后为每个实体创建一个映射类,例如Person:
public class PersonMap : IEntityTypeConfiguration<Person>
{
public void Map(EntityTypeBuilder<Person> builder)
{
builder.HasKey(x => x.Id);
builder.Property(x => x.Name).IsRequired().HasMaxLength(100);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,OnModelCreating你DbContext实现中的反射魔法:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Interface that all of our Entity maps implement
var mappingInterface = typeof(IEntityTypeConfiguration<>);
// Types that do entity mapping
var mappingTypes = typeof(DataContext).GetTypeInfo().Assembly.GetTypes()
.Where(x => x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
// Get the generic Entity method of the ModelBuilder type
var entityMethod = typeof(ModelBuilder).GetMethods()
.Single(x => x.Name == "Entity" &&
x.IsGenericMethod &&
x.ReturnType.Name == "EntityTypeBuilder`1");
foreach (var mappingType in mappingTypes)
{
// Get the type of entity to be mapped
var genericTypeArg = mappingType.GetInterfaces().Single().GenericTypeArguments.Single();
// Get the method builder.Entity<TEntity>
var genericEntityMethod = entityMethod.MakeGenericMethod(genericTypeArg);
// Invoke builder.Entity<TEntity> to get a builder for the entity to be mapped
var entityBuilder = genericEntityMethod.Invoke(builder, null);
// Create the mapping type and do the mapping
var mapper = Activator.CreateInstance(mappingType);
mapper.GetType().GetMethod("Map").Invoke(mapper, new[] { entityBuilder });
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我正在进行的项目中所做的工作.
public interface IEntityMappingConfiguration<T> where T : class
{
void Map(EntityTypeBuilder<T> builder);
}
public static class EntityMappingExtensions
{
public static ModelBuilder RegisterEntityMapping<TEntity, TMapping>(this ModelBuilder builder)
where TMapping : IEntityMappingConfiguration<TEntity>
where TEntity : class
{
var mapper = (IEntityMappingConfiguration<TEntity>)Activator.CreateInstance(typeof (TMapping));
mapper.Map(builder.Entity<TEntity>());
return builder;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
在Context的OnModelCreating方法中:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder
.RegisterEntityMapping<Card, CardMapping>()
.RegisterEntityMapping<User, UserMapping>();
}
Run Code Online (Sandbox Code Playgroud)
示例映射类:
public class UserMapping : IEntityMappingConfiguration<User>
{
public void Map(EntityTypeBuilder<User> builder)
{
builder.ToTable("User");
builder.HasKey(m => m.Id);
builder.Property(m => m.Id).HasColumnName("UserId");
builder.Property(m => m.FirstName).IsRequired().HasMaxLength(64);
builder.Property(m => m.LastName).IsRequired().HasMaxLength(64);
builder.Property(m => m.DateOfBirth);
builder.Property(m => m.MobileNumber).IsRequired(false);
}
}
Run Code Online (Sandbox Code Playgroud)
我喜欢利用Visual Studio 2015的折叠行为来做的另一件事是对于名为"User"的实体,将映射文件命名为"User.Mapping.cs",Visual Studio将折叠解决方案资源管理器中的文件这样它就包含在实体类文件中.
| 归档时间: |
|
| 查看次数: |
62244 次 |
| 最近记录: |