带有Sqlite的Dotnet核心:表关系

问题描述 投票:1回答:1

我已经在dotnet核心中启动了一个带有sqlite db的项目。我想了解表之间的关系是如何工作的。

这里的上下文和表格:

public class HallOfFameContext: DbContext
{
    public HallOfFameContext(DbContextOptions<HallOfFameContext> options)
        :base(options)
    { }

    public DbSet<Joke> Jokes { get; set; }
    public DbSet<User> Users { get; set; }
}

public class Joke
{
    public int JokeId { get; set; }
    public string Description { get; set; }
    public User Author { get; set; }
    public int Upvotes { get; set; }
    public int Downvotes { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }
}

如果数据库为空,我在应用程序启动时初始化数据库,如下所示:

context.Jokes.AddRange(
    new Joke
    {
        Description = "Perlinpinping",
        Author = new User
        {
            Name = "Claire"
        },
        Downvotes = 9354,
        Upvotes = 0
    },
    new Joke
    {
        Description = "Random Joke",
        Author = new User
        {
            Name = "Robouste"
        },
        Downvotes = 0,
        Upvotes = 78954
    }
);

当我检查我的数据库时,我发现系统足够聪明,可以在User表中添加用户,并只将id放在Joke表中。

Joke table

User table

到现在为止还挺好。现在的问题。当我检索笑话时,作者为空。

[HttpGet]
public IEnumerable<Joke> GetJokes()
{
    return _context.Jokes;
}

Json结果:

{"jokeId":1,"description":"Perlinpinping","author":null,"upvotes":0,"downvotes":9354}

当我尝试使用http post请求添加一个新的笑话时,我得到了一个unique constraint错误:

SqliteException:SQLite错误19:'UNIQUE约束失败:Users.UserId'。

这是有效负载请求:

{author: {userId: 2, name: "Robouste"}, description: "sdfsdfsd"}

行动:

[HttpPost]
public async Task<IActionResult> PostJoke([FromBody] Joke joke)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    _context.Jokes.Add(joke);
    await _context.SaveChangesAsync();

    return CreatedAtAction("GetJoke", new { id = joke.JokeId }, joke);
}

谁能解释我做错了什么?我认为这两个问题都与同样的原因有关,但我不明白为什么。

c# sqlite
1个回答
2
投票

EF Core尚不支持您的关系的延迟加载。

所以你需要使用eager loading方法Include你的关系:

[HttpGet]
public IEnumerable<Joke> GetJokes()
{
    return _context.Jokes.Include(joke => joke.Author);
}

或者使用explicit loading.

要解决更新问题,您应该查看有关使用disconnected entites的文档

在您的场景中,最简单的“修复”是从数据库中查找作者并在添加到上下文之前将其分配到joke对象:

    public async Task<IActionResult> PostJoke([FromBody] Joke joke)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        var author = _context.Find<User>(joke.Author.UserId);
        if (author != null)
        {
            //existing author
            joke.Author = author;
        }
        _context.Jokes.Add(joke);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetJoke", new { id = joke.JokeId }, joke);
    }
© www.soinside.com 2019 - 2024. All rights reserved.