1

我正在开发一个应用程序,在服务器上使用 asp.net core 2.2 和 ef core 2.2,在客户端使用 Angular 7。我无法弄清楚:

我有以下(简化的)模型:

public abstract class LegalEntity
{
    public int Id { get; set; }
    public int Name { get; set; }
    public Address FiscalAddress { get; set; }
}

public class Organisation : LegalEntity
{
    public Organisation(){}
    public Organisation(LegalEntityType legalEntityType, string name, Address fiscalAddress)
    {
        LegalEntityType = legalEntityType;
        Name = name;
    }
    public LegalEntityType LegalEntityType { get; set; }
}


public class LegalEntityType
{
    public int Id { get; set; }
    public int Name { get; set; }
    public LegalEntityType(){}
    public LegalEntityType(string name)
    {
        Name = name;
    }
}


public class Person : LegalEntity
{
    public Gender Gender { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public override string Name => string.Format("{0} {1}", FirstName, LastName);
}

public class Gender
{
    public int Id { get; set; }
    public int Name { get; set; }
}

public class Customer
{
    public int Id { get; set; }
    public Customer(){}
    public Customer(LegalEntity legalEntity)
    {
        LegalEntity = legalEntity;
    }
    public LegalEntity LegalEntity { get; set; }
}

当我通过 API 将客户实体返回给客户时,有时法人实体是一个组织,有时是一个人。在返回哪种类型(组织或个人)之后,我希望将属性 LegalEntityType(如果是组织)或属性 Gender(如果是个人)呈现到 JSON 代码中。这是我的第一个问题,以下使它们都为空:

.Include(o => o.Customer).ThenInclude(o => o.LegalEntity)

因为这不会加载仅存在于继承实体中的导航属性。这是 JSON 字符串的摘录,以防万一

人:

...
 "customer": {
            "legalEntity": {
                "gender": null,
                "firstName": "Denis",
                "lastName": "Testmann",
                "name": "Denis Testmann",
                "id": 9
            },
...

组织:

...
 "customer": {
            "legalEntity": {
                "legalEntityType": null,
                "name": "Companyname GmbH",
                "id": 6
            },
...

应该出现的是以下内容:

人:

...
 "customer": {
            "Person": {
                "gender": null,
                "firstName": "Denis",
                "lastName": "Testmann",
                "name": "Denis Testmann",
                "id": 9
            },
...

组织:

...
 "customer": {
            "Organisation": {
                "legalEntityType": null,
                "name": "Companyname GmbH",
                "id": 6
            },
...

明确一点:客户可能是个人或组织,实体(组织和个人)都从法人实体继承,因此客户财产“法人实体”有时是个人,有时是组织。当我呈现 JSON 时,必须维护特定类型。

希望我足够清楚 - 请原谅我这么久,我想确保问题得到理解。

4

2 回答 2

0

新答案

dotnet new console我通过 dotnet core 2.1将以下 Program.cs 放在一起:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Customer>();
        list.Add(new Customer(new Person { Gender = new Gender{ Name = "Male"}}));
        list.Add(new Customer(new Organisation { LegalEntityType = new LegalEntityType{ Name = "GmbH"}}));
        Console.WriteLine(JsonConvert.SerializeObject(list, Newtonsoft.Json.Formatting.Indented));
    }
}

public abstract class LegalEntity
{
   public int Id { get; set; }
   public virtual string Name { get; set; }
   public Address FiscalAddress { get; set; }
}

public class Organisation : LegalEntity
{
   public Organisation(){}
   public Organisation(LegalEntityType legalEntityType, string name, Address fiscalAddress)
   {
       LegalEntityType = legalEntityType;
       Name = name;
   }
   public LegalEntityType LegalEntityType { get; set; }
}


public class LegalEntityType
{
   public int Id { get; set; }
   public string Name { get; set; }
   public LegalEntityType(){}
   public LegalEntityType(string name)
   {
       Name = name;
   }
}

public class Person : LegalEntity
{
   public Gender Gender { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public override string Name => string.Format("{0} {1}", FirstName, LastName);
}

public class Gender
{
   public int Id { get; set; }
   public string Name { get; set; }
}


public class Customer
{
   public int Id { get; set; }
   public Customer(){}
   public Customer(LegalEntity legalEntity)
   {
       LegalEntity = legalEntity;
   }
   public LegalEntity LegalEntity { get; set; }
}    

public class Address
{
   public int Id { get; set; }
   public string Line1 { get; set; }
   public string Line2 { get; set; }   
}

输出如下所示:

[
  {
    "Id": 0,
    "LegalEntity": {
      "Gender": {
        "Id": 0,
        "Name": "Male"
      },
      "FirstName": null,
      "LastName": null,
      "Name": " ",
      "Id": 0,
      "FiscalAddress": null
    }
  },
  {
    "Id": 0,
    "LegalEntity": {
      "LegalEntityType": {
        "Id": 0,
        "Name": "GmbH"
      },
      "Id": 0,
      "Name": null,
      "FiscalAddress": null
    }
  }
]

这看起来好吗?也许检查您的 API 端点绑定器正在使用哪些序列化程序设置。

旧答案

如果 LegalEntity 是数据库中的真实表,您应该能够使用:

    [ForeignKey("LegalEntity")]
    public int LegalEntityId { get; set; }

在你的Customer定义中。

您还需要设置密钥:

    public abstract class LegalEntity
    {
        [Key]
        public int Id { get; set; }
        public int Name { get; set; }
        public Address FiscalAddress { get; set; }
    }

如果 LegalEntity 不是真正的表格,则为个人/组织添加单独的导航

于 2019-01-23T01:09:29.827 回答
0

好的 - 找到了解决方案!

在服务器端,您必须使用序列化 JSON 内容

SerializerSettings.TypeNameHandling = TypeNameHandling.Auto

您应该在 Startup.cs 文件中执行的操作:

    services.AddJsonOptions(opt =>
    {
        opt.SerializerSettings.ReferenceLoopHandling =
            Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        opt.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
    })

在客户端,您可以使用 class-transformer ( https://github.com/typestack/class-transformer )。

对于我的示例,客户类 - 其中 LegalEntity 可能是 Person 或 Organization 类型,如下所示:

public class Customer
   {
       public int Id { get; set; }

    @Type( () => Object, {
        discriminator: {
          property: '$type',
          subTypes: [
            {value: Person, name: 'Your.Name.Space.Person, YourApp.Name'},
            {value: Organisation, name: 'Your.Name.Space.Organisation, YourApp.Name'},
          ],
        },
      })
       public LegalEntity LegalEntity { get; set; }
   }

然后你从普通的 javascript 对象构建客户类的实例,如下所示:

    import { plainToClass } from 'class-transformer';

    export class SomeClassInYourAngularApp implements OnInit {

customerList: Customer[];

      ngOnInit() {
        this.customerList = new Array<Customer>();
        let u: any;

    // lets get the plain js object form somewhere, ex. from a resolver
        this.route.data.subscribe(data => {
          u = data['customerList'].result;
        });

        u = plainToClass(Customer, u);
        Object.assign(this.customerList, u);
      }

就是这样 !

于 2019-02-27T07:46:00.593 回答