.net - 如何使用asp .net web api、 Entity Framework 和json(代码优先)来回带关系的对象?

标签 .net asp.net-mvc json entity-framework code-first

使用 .NET 客户端应用程序,我试图通过 asp .net web api JSON 发布一个包含对象 B 集合的对象 A,创建一个 LocalDB 数据库并存储数据。然后再次获取对象A。

该应用程序包括 3 个项目。一个 asp .net mvc 4 web api 项目、一个 .Net 控制台应用程序和一个 .Net 类库。 asp .net 应用程序和控制台应用程序都引用了类库,其中包括对象 A 和 B 的类定义。

类库:

public class Actor
{
    public Actor()
    {
        this.Movies = new HashSet<Movie>();
    }

    public int ActorID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Movie> Movies { get; set; }
}

public class Movie
{
    public Movie()
    {
        this.Actors = new HashSet<Actor>();
    }

    public int MovieID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Actor> Actors { get; set; }
}

控制台应用程序:
Movie movie = new Movie()
{
    Name = "Dr. No"
};

Actor actor = new Actor()
{
    Name = "Sean Connery"
};

movie.Actors.Add(actor);

using (HttpClient client = new HttpClient())
{
    client.BaseAddress = new Uri("http://localhost:3654");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var response = client.PostAsJsonAsync<Movie>("api/movies", movie).Result;
    response.EnsureSuccessStatusCode();

    response = client.GetAsync("api/movies/1").Result;
    response.EnsureSuccessStatusCode();

    Movie newMovie = response.Content.ReadAsAsync<Movie>().Result;
}

asp .net mvc DbContext:
public class MediaContext : DbContext
{
    public MediaContext()
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    public DbSet<Movie> Movies { get; set; }
    public DbSet<Actor> Actors { get; set; }
}

问题#1: JSON 似乎不喜欢循环引用,但是如果我不将集合添加到两个对象,EF5 不会创建 MoviesActors 表来保存引用。

问题#2:即使我在 Controller 中添加了引用,当我返回该对象时,它也不会与 Actors 一起返回它。例如。我期待像
Movie
{
   MovieID = "1",
   Name = "???",
   Actors[] = { 1 }
}

但相反,Actors 只是空值。

更新 :这是自引用异常:

ExceptionMessage=检测到类型为“System.Data.Entity.DynamicProxies.Movie_157D88BDC89E46A7CE4875C2970C7BBFB893972095EFA0745C2261AACC007969”的自引用循环。路径“[0].Actors[0].Movies”。

我设法使用 How did I solve the Json serializing circular reference error? 中的方法解决了这个异常。并且只是禁用代理。这解决了问题#1。但是,当我获得电影时,即使使用 Include("Actors"),它们仍然没有 Actor 。我可以看到在 LocalDb 的中间表中正确创建了引用。

更新 2

终于想通了,下面回答。

非常感谢!

最佳答案

经过大量搜索,我终于能够解决我的问题。最初我尝试将 [ScriptIgnore] 标记添加到电影集,但是我使用的是 EF5 final,它将默认序列化程序更改为 JSON .NET。我终于发现 [ScriptIgnore] 不起作用,我不得不像这样设置 [JsonIgnore]:

public class Actor
{
    public int ActorID { get; set; }
    public string Name { get; set; }

    [JsonIgnore]
    public virtual ICollection<Movie> Movies { get; set; }
}

public class Movie
{
    public int MovieID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Actor> Actors { get; set; }
}

结合 Get 方法中的 .Include("Actors") 急切加载,最终解决了我的问题。

总之,我需要:
  • 在两个对象上都有虚拟 ICollection 引用以创建中间表。
  • 在 Movies 集合引用中添加 [JsonIgnore] 以解决循环引用。
  • 关闭代理解决我的500错误。
  • 使用 .Include("Actors")
  • 在 GetMovies/GetMovie 方法中加载 Actors

    此外,我发现对于 Movie 对象的后续 PUT,其中 Actors 集合已更改,我必须手动将每个子 Actor 上的 RelationShip 状态更改为已添加/已删除,以确保相关集合已更新。

    关于.net - 如何使用asp .net web api、 Entity Framework 和json(代码优先)来回带关系的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12022233/

    相关文章:

    C# - 将 Regex 与 TextBox.Validating 结合使用

    c# - 如何构造指定精度和小数位数的 SqlDecimal 数据类型的实例

    asp.net-mvc - 你是如何填充/验证你的 ViewModel 的?

    c# - 在 Mvc4/C# 中实现 Google Analytics?

    javascript - 解析 JSON - Javascript - 未定义

    .net - 如何强制使用MSBuild版本?

    c# - 如何防止 .NET 库在关闭时发送 RST 数据包

    c# - ViewBag 属性在单元测试中始终返回 null

    javascript - 循环数据对象并输出每个对象的对象文件名和消息

    json - golang - 将结构格式化为 json