C# Fixture配置OmitAutoProperties时如何保留实体Id与User.Id
实现方式
在启用OmitAutoProperties配置时,你完全可以做到仅保留主键、外键的自动生成,其余属性遵循省略填充规则,不需要修改全局配置,两种常用写法如下:
单次构建适配(直接修改你现有代码即可)
OmitAutoProperties的规则优先级低于链式调用中显式声明的属性生成规则,你只需要在Build链中对需要自动生成的Id属性单独声明即可,不需要手动赋值:
// 建议共用同一个Fixture实例,避免重复初始化带来的性能损耗 var fixture = new Fixture(); var user = fixture.Build<User>() .OmitAutoProperties() // 开启自动属性省略 .With(x => x.Id) // 声明User.Id保留自动生成 .Create(); var entity = fixture.Build<Game>() .OmitAutoProperties() // 开启自动属性省略 .With(x => x.Id) // 声明Game主键Id保留自动生成 // 如果Game实体有显式定义的外键属性UserId,加下面这行即可保留自动生成 // .With(x => x.UserId) .With(x => x.User, user) // 保留你原本的关联用户赋值逻辑 .Create();
上述代码生成的实体中,只有你显式声明的Id属性、手动赋值的User属性会有值,其余所有属性都会保持类型默认值,完全符合需求。
全局统一配置(适合测试项目复用)
如果你的项目中所有实体测试都遵循"仅自动生成Id、其余属性省略"的规则,可以封装扩展方法统一逻辑,避免每次Build都重复写Id声明:
public static class FixtureExtensions { public static IPostprocessComposer<T> BuildTestEntity<T>(this IFixture fixture) where T : class { var idProp = typeof(T).GetProperty("Id"); var composer = fixture.Build<T>().OmitAutoProperties(); if (idProp != null && idProp.CanWrite) { // 显式指定Id属性由AutoFixture按类型自动生成值 composer = composer.With( x => idProp.GetValue(x), () => fixture.Create(idProp.PropertyType) ); } return composer; } }
封装后你可以直接调用扩展方法构建实体,默认就会开启OmitAutoProperties且保留Id自动生成:
var user = fixture.BuildTestEntity<User>().Create(); var entity = fixture.BuildTestEntity<Game>().With(x => x.User, user).Create();
注意:不需要为Id属性手动写死固定值,AutoFixture会自动按属性类型生成唯一值,支持int、Guid等常见主键类型,不会出现多实体Id重复的问题。
内容的提问来源于stack exchange,提问作者Дмитрий Власов
相关产品推荐
相关产品推荐

