c# - 如何使用 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。我确实希望这有助于消除混乱并理解我遇到的问题。
如果您有更多问题,请在我尝试将其保存到数据库时告诉我。
解决方案
如果我对您的理解正确并且您想要的只是将您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));
推荐阅读
- jquery - 计算 $(this) 之前的类实例
- java - EJB,JPA persistance.xml 问题 Wildfly 8.2 intellij
- jasmine - 下拉列表中的元素不可交互。如何获取元素?
- php - 代码点火器不允许上传视频文件
- java - 如何将包从一个项目导入到另一个项目
- c++ - 如何格式化 Registry->Shell->Open->Command(从 AssocQueryString 输出)
- java - 增量/减量运算符无法正常工作
- python - IOError: [Errno 2] No such file or directory - 在 linux 上,使用绝对路径
- angular6 - 如何根据条件更改角度地图标记颜色?
- octave - 如何访问 Gnu Octave 中不同目录中定义的函数?