You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Дмитрий Власов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:54:16