Entity Framework 只保存了我的一些字段
Entity Framework only saving some of my fields
我正在尝试编写一个小型网站 api,这是我第一次使用 entity framework。
我的问题是只保存了部分数据。
我有这个 GET 方法,它只是用来将模型保存到数据库中:
[HttpGet]
public async Task<IActionResult> PopulateDB()
{
var playerOneQuest = new StatusModel
{
PlayerId = "1",
points= 250,
completedSteps = new List<Status>()
{
new Status
{
Id = 11,
Index = 1
}
}
};
_context.Quest.Add(playerOneQuest);
await _context.SaveChangesAsync();
return Ok("Added data"); // Breakpoint here
}
当我在最后一行添加断点时,_context
看起来所有数据都很好,但是一旦方法执行完毕,completedSteps
就会为空。其他数据 - PlayerId
& points
- 保存得很好。
我尝试在调用 SaveChangesAsync()
之前添加这个 _context.Entry(playerOneQuest).State = EntityState.Added;
,但是 completedSteps
在方法执行后仍然以 null 结束。
_context
定义为:
public class QuestContext : DbContext
{
public QuestContext(DbContextOptions<QuestContext> options)
: base(options){ }
public virtual DbSet<StatusModel> Quest { get; set; } = null!;
}
使用的2个模型定义为:
public class StatusModel
{
[Key]
public string? PlayerId {get;set;}
public long Points{get;set;}
public List<Status> completedSteps {get;set;} = null!;
}
public class Status
{
public long Id {get;set;}
public int Index {get;set;}
}
为了更好的衡量,这是将数据库上下文添加到我的网络应用程序的方式:
builder.Services.AddDbContext<QuestContext>(opt =>
opt.UseInMemoryDatabase("Quests"));
型号中:
public class StatusModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id {get;set;}
public long Points{get;set;}
public List<Status> completedSteps {get;set;} = new List<Status>();
}
public class Status
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id {get;set;}
public int Index {get;set;}
public long StatusModelId {get;set;}
public StatusModel {get;set;}
}
在 OnModelCreating
中的存储上下文中:
modelBuilder.Entity<Status>().HasOne(c => c.StatusModel).WithMany(c => c.completedSteps)
.HasForeignKey(c => c.StatusModelId).OnDelete(DeleteBehavior.Cascade);
您必须设置对象之间的关系。您可以在您的 Context 中使用 fluent API 或直接在模型中使用属性。同样在您的上下文中,您需要两个 DbSets,用于状态和 statusModel。
未经测试就写了答案,不过应该足够接近了。这里有一个link关系:Relations in EF
我错过了你的 PlayerId - 我猜这是对 Player 的 FK?比你还必须建立这种关系。如果您打算将其用作 PK,则它可能不应该为空。
问题是您没有指定要加载其他数据。
https://docs.microsoft.com/en-us/ef/core/querying/related-data/
您可以通过代理启用延迟加载:https://docs.microsoft.com/en-us/ef/core/querying/related-data/lazy 或通过在查询中使用 .Include()
来明确。
var completeList = await _questContext.Quest.Include(i => i.completedSteps).ToListAsync();
据我所知,您的实体已按照约定正确设置。这意味着当您只想拥有一个简单的 one-to-many 关系时,您不需要配置任何关于实体的额外内容。
注入 QuestContext
的控制器示例:
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly QuestContext _questContext;
public MyController(QuestContext questContext)
{
_questContext = questContext;
}
[HttpGet]
public async Task<NoContentResult> Get()
{
var playerOneQuest = new StatusModel
{
PlayerId = "1",
Points = 250,
completedSteps = new List<Status>()
{
new Status
{
Id = 11,
Index = 1
}
}
};
_questContext.Quest.Add(playerOneQuest);
await _questContext.SaveChangesAsync();
return NoContent();
}
[HttpGet("check")]
public async Task<List<StatusModel>> Check()
{
var completeList = await _questContext.Quest.Include(i => i.completedSteps).ToListAsync();
return completeList;
}
}
我正在尝试编写一个小型网站 api,这是我第一次使用 entity framework。
我的问题是只保存了部分数据。
我有这个 GET 方法,它只是用来将模型保存到数据库中:
[HttpGet]
public async Task<IActionResult> PopulateDB()
{
var playerOneQuest = new StatusModel
{
PlayerId = "1",
points= 250,
completedSteps = new List<Status>()
{
new Status
{
Id = 11,
Index = 1
}
}
};
_context.Quest.Add(playerOneQuest);
await _context.SaveChangesAsync();
return Ok("Added data"); // Breakpoint here
}
当我在最后一行添加断点时,_context
看起来所有数据都很好,但是一旦方法执行完毕,completedSteps
就会为空。其他数据 - PlayerId
& points
- 保存得很好。
我尝试在调用 SaveChangesAsync()
之前添加这个 _context.Entry(playerOneQuest).State = EntityState.Added;
,但是 completedSteps
在方法执行后仍然以 null 结束。
_context
定义为:
public class QuestContext : DbContext
{
public QuestContext(DbContextOptions<QuestContext> options)
: base(options){ }
public virtual DbSet<StatusModel> Quest { get; set; } = null!;
}
使用的2个模型定义为:
public class StatusModel
{
[Key]
public string? PlayerId {get;set;}
public long Points{get;set;}
public List<Status> completedSteps {get;set;} = null!;
}
public class Status
{
public long Id {get;set;}
public int Index {get;set;}
}
为了更好的衡量,这是将数据库上下文添加到我的网络应用程序的方式:
builder.Services.AddDbContext<QuestContext>(opt =>
opt.UseInMemoryDatabase("Quests"));
型号中:
public class StatusModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id {get;set;}
public long Points{get;set;}
public List<Status> completedSteps {get;set;} = new List<Status>();
}
public class Status
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id {get;set;}
public int Index {get;set;}
public long StatusModelId {get;set;}
public StatusModel {get;set;}
}
在 OnModelCreating
中的存储上下文中:
modelBuilder.Entity<Status>().HasOne(c => c.StatusModel).WithMany(c => c.completedSteps)
.HasForeignKey(c => c.StatusModelId).OnDelete(DeleteBehavior.Cascade);
您必须设置对象之间的关系。您可以在您的 Context 中使用 fluent API 或直接在模型中使用属性。同样在您的上下文中,您需要两个 DbSets,用于状态和 statusModel。
未经测试就写了答案,不过应该足够接近了。这里有一个link关系:Relations in EF
我错过了你的 PlayerId - 我猜这是对 Player 的 FK?比你还必须建立这种关系。如果您打算将其用作 PK,则它可能不应该为空。
问题是您没有指定要加载其他数据。
https://docs.microsoft.com/en-us/ef/core/querying/related-data/
您可以通过代理启用延迟加载:https://docs.microsoft.com/en-us/ef/core/querying/related-data/lazy 或通过在查询中使用 .Include()
来明确。
var completeList = await _questContext.Quest.Include(i => i.completedSteps).ToListAsync();
据我所知,您的实体已按照约定正确设置。这意味着当您只想拥有一个简单的 one-to-many 关系时,您不需要配置任何关于实体的额外内容。
注入 QuestContext
的控制器示例:
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly QuestContext _questContext;
public MyController(QuestContext questContext)
{
_questContext = questContext;
}
[HttpGet]
public async Task<NoContentResult> Get()
{
var playerOneQuest = new StatusModel
{
PlayerId = "1",
Points = 250,
completedSteps = new List<Status>()
{
new Status
{
Id = 11,
Index = 1
}
}
};
_questContext.Quest.Add(playerOneQuest);
await _questContext.SaveChangesAsync();
return NoContent();
}
[HttpGet("check")]
public async Task<List<StatusModel>> Check()
{
var completeList = await _questContext.Quest.Include(i => i.completedSteps).ToListAsync();
return completeList;
}
}