如何在 Table 关系 C# ASP .NET Entity Framework Core 6 Web API 中按 LINQ 方法语法中的 table 名称对列进行分组?

How to group columns by table name in LINQ Method Syntax in Table Relationships C# ASP .NET Entity Framework Core 6 Web API?

我是 C# 新手 ASP.Net Entity Framework。我正在尝试构建一个 API 并且我想生成这样的输出:

[
    {
        
        "userId": 1275,
        "username": "dmartin",
        "email": "Dan.Martin@i-s-consulting.com",
        "firstName": "Dan",
        "middleInitial": "",
        "lastName": "Martin",
        "isApproved": true,
        "lastActivityDate": "2012-10-05T12:23:24.253",
        "lastLoginDate": "2021-10-27T09:13:56.597",
        "lastPasswordChangedDate": "2020-07-29T16:06:41.863",
        "creationDate": "2010-04-07T22:51:14",
        "Iscinstance":[
            {
                "iscinstanceId": 236,
                "name": "ABA"
            }
        ],
        "UserProfile":[
            {
                "profileName": "",
                "address1": "",
                "directConnectPhone": "",
                "profileEmail": "",
                "profile": null
            }
        ]
    }
]

这个 class 是用 table 关系创建的:

用户Table

[DataContract]
public partial class User
{
    [DataMember]
    public int UserId { get; set; }
    [DataMember]
    public string Username { get; set; }
    [DataMember]
    public string Email { get; set; }
    [DataMember]
    public bool IsApproved { get; set; }
    [DataMember]
    public DateTime? LastActivityDate { get; set; }
    [DataMember]
    public DateTime? LastLoginDate { get; set; }
    [DataMember]
    public DateTime? LastPasswordChangedDate { get; set; }
    [DataMember]
    public DateTime? CreationDate { get; set; }
    [DataMember]
    public string FirstName { get; set; }
    [DataMember]
    public string LastName { get; set; }
    [DataMember]
    public string MiddleInitial { get; set; }

    public virtual UserProfile Profile { get; set; }
    public virtual LinkUsersToIscinstance LinkUsersToIscinstances { get; set; }
    
}

用户资料Table

[DataContract]
public partial class UserProfile
{
    public UserProfile()
    {
        LinkUsersToIscinstances = new HashSet<LinkUsersToIscinstance>();
        Users = new HashSet<User>();
    }
    [DataMember]
    public int ProfileId { get; set; }
    [DataMember]
    public string ProfileName { get; set; }
    [DataMember]
    public string Email { get; set; }
    [DataMember]
    public string DirectConnectPhone { get; set; }
    [DataMember]
    public string EmergencyContactNumber { get; set; }
    [DataMember]
    public string Address1 { get; set; }
    [DataMember]
    public string Address2 { get; set; }
    [DataMember]
    public string County { get; set; }
    [DataMember]
    public int State { get; set; }
    [DataMember]
    public string Zip { get; set; }
    [DataMember]
    public string EmergencyCell { get; set; }
    
    public virtual ICollection<LinkUsersToIscinstance> LinkUsersToIscinstances { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

LinkUsersToIscinstance Table

[DataContract(IsReference = true)]
public partial class LinkUsersToIscinstance
{
    public LinkUsersToIscinstance()
    {
        Users = new HashSet<User>();
    }
    public int LinkId { get; set; }
    [DataMember]
    public int IscinstanceId { get; set; }
    [DataMember]
    public int UserId { get; set; }

    public virtual UserProfile Profile { get; set; }
    public virtual Iscinstance Iscinstances { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

Iscinstance Table

[DataContract]
public partial class Iscinstance
{
    public Iscinstance()
    {
        LinkUsersToIscinstances = new HashSet<LinkUsersToIscinstance>();
    }
    [DataMember]
    public int IscinstanceId { get; set; }
    [DataMember]
    public string Name { get; set; }

    public virtual ICollection<LinkUsersToIscinstance> LinkUsersToIscinstances { get; set; }
}

我还创建了一个自定义 class 但我认为不会需要它,这里是 :

[DataContract]
public class CustomClass
{
    [DataMember]
    public int IscinstanceId { get; set; }
    //[DataMember(Name = "ISCInstanceName")]
    [DataMember]
    public string? Name { get; set; }
    [DataMember]
    public int UserId { get; set; }
    [DataMember]
    public string? Username { get; set; }
    [DataMember]
    public string? Email { get; set; }
    [DataMember]
    public string? FirstName { get; set; }
    [DataMember]
    public string? MiddleInitial { get; set; }
    [DataMember]
    public string? LastName { get; set; }
    [DataMember]
    public bool IsApproved { get; set; }
    [DataMember]
    public DateTime? LastActivityDate { get; set; }
    [DataMember]
    public DateTime? LastLoginDate { get; set; }
    [DataMember]
    public DateTime? LastPasswordChangedDate { get; set; }
    [DataMember]
    public DateTime? CreationDate { get; set; }
    [DataMember]
    public string? ProfileName { get; internal set; }
    [DataMember]
    public string? Address1 { get; internal set; }
    [DataMember]
    public string? DirectConnectPhone { get; internal set; }
    [DataMember]
    public string? ProfileEmail { get; internal set; }
}

这是我的查询:

 var customer = await _context.Users
                            .Where(c => c.UserId  == UserId && c.LastActivityDate > date && c.IsApproved == num)
                            .Include(c => c.Profile)
                            .Include(c => c.LinkUsersToIscinstances).ThenInclude(c => c.Iscinstances)
                            .OrderBy(c => c.LinkUsersToIscinstances.Iscinstances.Name).ThenBy(c => c.LastName).ThenBy(c => c.FirstName)
                            .Select(c => new CustomClass
                            {
                                IscinstanceId = c.LinkUsersToIscinstances.Iscinstances.IscinstanceId,
                                Name = c.LinkUsersToIscinstances.Iscinstances.Name,

                                UserId = c.UserId,
                                Username = c.Username,
                                Email = c.Email,
                                FirstName= c.FirstName,
                                MiddleInitial= c.MiddleInitial,
                                LastName= c.LastName,
                                IsApproved= c.IsApproved,
                                LastActivityDate= c.LastActivityDate,
                                LastLoginDate= c.LastLoginDate,
                                LastPasswordChangedDate= c.LastPasswordChangedDate,
                                CreationDate= c.CreationDate,

                                ProfileName = c.Profile.ProfileName,
                                ProfileEmail = c.Profile.Email,
                                DirectConnectPhone = c.Profile.DirectConnectPhone,
                                Address1 = c.Profile.Address1

                                })
                            .ToListAsync();

这是我当前的输出

[
    {
        "iscinstanceId": 236,
        "name": "ABA",
        "userId": 1275,
        "username": "dmartin",
        "email": "Dan.Martin@i-s-consulting.com",
        "firstName": "Dan",
        "middleInitial": "",
        "lastName": "Martin",
        "isApproved": true,
        "lastActivityDate": "2012-10-05T12:23:24.253",
        "lastLoginDate": "2021-10-27T09:13:56.597",
        "lastPasswordChangedDate": "2020-07-29T16:06:41.863",
        "creationDate": "2010-04-07T22:51:14",
        "profileName": "",
        "address1": "",
        "directConnectPhone": "",
        "profileEmail": "",
        "profile": null
    }
]

希望有人能帮助我:(

从你的后端代码来看,似乎一个 User 有一个 UserProfileIscinstance,但你期望的 json 这里是一个 List 对象:

"Iscinstance":[
        {
            "iscinstanceId": 236,
            "name": "ABA"
        }
    ],
    "UserProfile":[
        {
            "profileName": "",
            "address1": "",
            "directConnectPhone": "",
            "profileEmail": "",
            "profile": null
        }
    ]

如果您真的想要这种 json,您需要将 CustomClass 更改为:

public class CustomClass
{
    public int UserId { get; set; }
    public string? Username { get; set; }
    public string? Email { get; set; }
    public string? FirstName { get; set; }
    public string? MiddleInitial { get; set; }
    public string? LastName { get; set; }
    public bool IsApproved { get; set; }
    public DateTime? LastActivityDate { get; set; }
    public DateTime? LastLoginDate { get; set; }
    public DateTime? LastPasswordChangedDate { get; set; }
    public DateTime? CreationDate { get; set; }
    public dynamic? Iscinstance { get; set; }
    public dynamic? UserProfile { get; set; }
}

控制器:

    var customer = await _context.User
                .Where(c => c.UserId  == UserId && c.LastActivityDate > date && c.IsApproved == num)
                
                .OrderBy(c => c.LinkUsersToIscinstances.Iscinstances.Name).ThenBy(c => c.LastName).ThenBy(c => c.FirstName)
                .Select(c => new TestModel
                {
                    UserId = c.UserId,
                    Username = c.Username,
                    Email = c.Email,
                    FirstName = c.FirstName,
                    MiddleInitial = c.MiddleInitial,
                    LastName = c.LastName,
                    IsApproved = c.IsApproved,
                    LastActivityDate = c.LastActivityDate,
                    LastLoginDate = c.LastLoginDate,
                    LastPasswordChangedDate = c.LastPasswordChangedDate,
                    CreationDate = c.CreationDate,
                    Iscinstance = new [] {
                        new {
                            IscinstanceId= c.LinkUsersToIscinstances.Iscinstances.IscinstanceId,
                            Name = c.LinkUsersToIscinstances.Iscinstances.Name
                        }
                    },
                    UserProfile = new []{
                        new {
                            ProfileName = c.Profile.ProfileName,
                            ProfileEmail = c.Profile.Email,
                            DirectConnectPhone = c.Profile.DirectConnectPhone,
                            Address1 = c.Profile.Address1
                        }
                    }
                })
                .ToListAsync();

首先,您需要一些 类 来表示预期的 json 结果:

public class UserModel
{
    public int UserId { get; set; }
    public string? Username { get; set; }
    public string? Email { get; set; }
    public string? FirstName { get; set; }
    public string? MiddleInitial { get; set; }
    public string? LastName { get; set; }
    public bool IsApproved { get; set; }
    public DateTime? LastActivityDate { get; set; }
    public DateTime? LastLoginDate { get; set; }
    public DateTime? LastPasswordChangedDate { get; set; }
    public DateTime? CreationDate { get; set; }
    public IEnumerable<IscinstanceModel> Iscinstance { get; set; }
    public IEnumerable<UserProfileModel> UserProfile { get; set; }
}

public class IscinstanceModel
{
    public int IscinstanceId { get; set; }
    public string? Name { get; set; }
}

public class UserProfileModel
{
    public string? ProfileName { get; set; }
    public string? Address1 { get; set; }
    public string? DirectConnectPhone { get; set; }
    public string? ProfilEmail { get; set; }
    public string? Profile { get; set; }
}

然后您可以将实体转换为 api 模型,例如:

var customers = await _context.Users
    .Where(c => c.UserId  == UserId && c.LastActivityDate > date && c.IsApproved == num)
    .Include(c => c.Profile)
    .Include(c => c.LinkUsersToIscinstances).ThenInclude(c => c.Iscinstances)
    .OrderBy(c => c.LinkUsersToIscinstances.Iscinstances.Name).ThenBy(c => c.LastName).ThenBy(c => c.FirstName)
    .Select(c => new UserModel
    {
        UserId = c.UserId,
        Username = c.Username,
        Email = c.Email,
        FirstName = c.FirstName,
        MiddleInitial = c.MiddleInitial,
        LastName = c.LastName,
        IsApproved = c.IsApproved,
        LastActivityDate = c.LastActivityDate,
        LastLoginDate = c.LastLoginDate,
        LastPasswordChangedDate = c.LastPasswordChangedDate,
        CreationDate = c.CreationDate,
        Iscinstance = c.LinkUsersToIscinstances
            .SelectMany(l => l.Iscinstances)
            .Select(i =>
                new IscinstanceModel {
                    IscinstanceId = l.IscinstanceId,
                    Name = l.name
                }
            ),
        UserProfile = new [] {
            new UserProfileModel{
                ProfileName = c.Profile.ProfileName,
                Address1 = c.Profile.Address1,
                DirectConnectPhone = c.Profile.DirectConnectPhone,
                ProfilEmail = c.Profile.ProfilEmail
            }
        }
    })
    .ToListAsync();

预期的 json 具有用户个人资料列表,但实体只有一个个人资料。在这种情况下,只需将配置文件封装在一个集合中即可。同iscinstance.