首页 > 解决方案 > 如何使用 EntityFramework 将作为字符串列表作为字段之一的 JSON 对象存储到 SQL 中

问题描述

因此,我看到了以下 JSON:

[
  {
        "Title": "TOY STORY 4",
        "GENRE": "COMEDY",
        "Actors": [
            "Tom Hanks",
            "Tim Allen",
            "Annie Potts"
        ],
        "Id": 1
    },
    {
        "Title": "The Matrix",
        "GENRE": "Action",
        "Actors": [
            "Keanu Reeves",
            "Laurence Fishburne",
            "Carrie-Anne Moss"
        ],
        "Id": 2
    }
]

C# object 

class Movies
{
 public string Title {get; set;}
 public string GENRE {get; set;}
 public string[] Actors {get; set;}
 public int id {get; set;}
}

当我为电影创建控制器时,它没有演员列,也没有为演员创建新表。

电影控制器

 public class MoviesController : ApiController
{
    private DataContext db = new DataContext();

    // GET: api/Movies
    public IQueryable<Movies> GetMovies()
    {
        return db.Movies;
    }

    // GET: api/Movies/5
    [ResponseType(typeof(Movies))]
    public IHttpActionResult GetMovies(int id)
    {
        Movies movies = db.Movies.Find(id);
        if (movies == null)
        {
            return NotFound();
        }

        return Ok(movies);
    }

    // PUT: api/Movies/5
    [ResponseType(typeof(void))]
    public IHttpActionResult PutMovies(int id, Movies movies)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != movies.id)
        {
            return BadRequest();
        }

        db.Entry(movies).State = EntityState.Modified;

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MoviesExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/Movies
    [ResponseType(typeof(Movies))]
    public IHttpActionResult PostMovies(Movies movies)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Movies.Add(movies);
        db.SaveChanges();

        return CreatedAtRoute("DefaultApi", new { id = movies.id }, movies);
    }

    // DELETE: api/Movies/5
    [ResponseType(typeof(Movies))]
    public IHttpActionResult DeleteMovies(int id)
    {
        Movies movies = db.Movies.Find(id);
        if (movies == null)
        {
            return NotFound();
        }

        db.Movies.Remove(movies);
        db.SaveChanges();

        return Ok(movies);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

    private bool MoviesExists(int id)
    {
        return db.Movies.Count(e => e.id == id) > 0;
    }
}

这是我将 Actors 作为对象的另一个:

 public class Movies1
{
    public string Title { get; set; }
    public string GENRE { get; set; }
    public List<Actor> Actors { get; set; }
    public int id { get; set; }
}

    public class Actor
{
  public string Actors { get; set; }
  public int Id { get; set; }
}

电影1控制器:

 public class Movies1Controller : ApiController
{
    private DataContext db = new DataContext();

    // GET: api/Movies1
    public IQueryable<Movies1> GetMovies1()
    {
        return db.Movies1;
    }

    // GET: api/Movies1/5
    [ResponseType(typeof(Movies1))]
    public IHttpActionResult GetMovies1(int id)
    {
        Movies1 movies1 = db.Movies1.Find(id);
        if (movies1 == null)
        {
            return NotFound();
        }

        return Ok(movies1);
    }

    // PUT: api/Movies1/5
    [ResponseType(typeof(void))]
    public IHttpActionResult PutMovies1(int id, Movies1 movies1)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != movies1.id)
        {
            return BadRequest();
        }

        db.Entry(movies1).State = EntityState.Modified;

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!Movies1Exists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/Movies1
    [ResponseType(typeof(Movies1))]
    public IHttpActionResult PostMovies1(Movies1 movies1)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Movies1.Add(movies1);
        db.SaveChanges();

        return CreatedAtRoute("DefaultApi", new { id = movies1.id }, movies1);
    }

    // DELETE: api/Movies1/5
    [ResponseType(typeof(Movies1))]
    public IHttpActionResult DeleteMovies1(int id)
    {
        Movies1 movies1 = db.Movies1.Find(id);
        if (movies1 == null)
        {
            return NotFound();
        }

        db.Movies1.Remove(movies1);
        db.SaveChanges();

        return Ok(movies1);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

    private bool Movies1Exists(int id)
    {
        return db.Movies1.Count(e => e.id == id) > 0;
    }
}

这是两者的结果,他们都没有将 Actors 写入 DB。我确实希望这有助于消除混乱并理解我遇到的问题。

如果您有更多问题,请在我尝试将其保存到数据库时告诉我。

SQL 中的表

标签: c#json.net

解决方案


如果我对您的理解正确并且您想要的只是将您Actors作为原始 json 字符串存储在 Db 中,您可以向您的 DbContextOnModelCreating方法添加一个值转换器,如下所示:

using System.Text.Json;

public class MyDbContext : DbContext
{
    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        ...
        
        modelBuilder
            .Entity<Movies>()
            .Property(m => m.Actors)
            .HasConversion(
                a => JsonSerializer.Serialize(a),
                a => JsonSerializer.Deserialize<string[]>(a));
    }   
}

简而言之,它告诉 EFActors在写入/读取数据库时序列化/反序列化。

编辑:
因为你有一个json.net标签,这就是你为你的特定包裹做的方式。

using Newtonsoft.Json;

...
// Everything else remains the same.
.HasConversion(
    a => JsonConvert.SerializeObject(a),
    a => JsonConvert.DeserializeObject<string[]>(a));

推荐阅读