我有一个包含数据库中用户的银行帐户类型的表,如下所示
BankAcctTypes
| ID | UserID | AcctType | AcctNo |
------------------------------------------------
| 1 | User1 | Single | 1234 |
| 2 | User2 | Single | 2345 |
| 3 | User2 | Joint | 3456 |
| 4 | User2 | Joint | 4567 |
| 5 | User3 | Joint | 5678 |
| 6 | User3 | Joint | 6789 |
| 7 | User4 | Single | 7890 |
| 9 | User4 | Single | 8901 |
| 10 | User5 | Joint | 9012 |
------------------------------------------------
**用户可以拥有任意数量的联合和单一行为,也可以是任何组合。任何没有用户帐户的用户都没有在给定的表格中找到。
现在要求是根据以下规则从此表中获取所有用户及其银行帐户类型
single
类型的银行帐户(一个或多个)返回Single
Joint
类型的银行帐户(一个或多个)返回Joint
Joint
或Single
(任意组合)的混合返回Joint
ps:要返回的多个accts中的任何一个。没有限制
预期结果:
| ID | UserID | AcctType | AcctNo |
---------------------------------------------
| 1 | User1 | Single | xxxxxx |
| 2 | User2 | Joint | xxxxxx | (any one of Joint acct)
| 3 | User3 | Joint | xxxxxx |
| 4 | User4 | Single | xxxxxx | (any one of Joint acct)
| 5 | User5 | Joint | xxxxxx |
---------------------------------------------
请帮我构建LINQ语句/ SQL语句。
答案 0 :(得分:1)
我根据您的示例数据创建了以下模型:
public enum AcctType
{
Single,
Joint
}
public class Account
{
public int ID;
public string UserID;
public AcctType AcctType;
public int AcctNo;
}
此查询应该适合您:
var result = from account in accounts
group account by account.UserID
into grouping
select grouping.Any(account => account.AcctType == AcctType.Joint) && grouping.Any(account => account.AcctType == AcctType.Single)
? grouping.Where(account => account.AcctType == AcctType.Joint).Take(1)
: grouping.ToList();
这是做什么的:
UserID
修改强>
对不起,我没注意到你在使用EF。 您收到此错误的原因是因为LINQ to SQL不支持树状结果。这意味着在单个查询中执行此操作是不可能的。
您必须将其拆分:
var groupings = accounts.GroupBy(account => account.UserID);
var joint = groupings.Where(grouping => grouping.Any(account => account.AcctType == AcctType.Joint) && grouping.Any(account => account.AcctType == AcctType.Single));
var result = joint.Select(grouping => grouping.First(account => account.AcctType == AcctType.Joint)).Concat(groupings.Except(joint).SelectMany(grouping => grouping.ToList()));
分为3个操作并不优雅,但必须避免重复某些操作,例如group-by。
答案 1 :(得分:0)
您写道:
要求是使用银行帐户类型获取所有用户 已提供
因此,结果主要是用户的属性,他们提供的银行账户的一些属性,以及关于单一和联合银行账户的一些责任。
后来你写道:
可能存在多个单一行为且没有关节的用户 行为以及反之亦然。
您的要求不完整。
正确指定:
未指定:
您可以决定使用用户拥有的AcctType返回所有银行帐户类型的UserId,AcctType和一系列AcctNo。
您还可以决定为每个银行帐户类型重复UserId和AcctType。
当然第一个更有效率,因为UserId和AcctType只被提取一次,即使用户有数百个银行账户。
假设您有一个正确的Entity-Framework类定义,其中User和BankAccountType之间存在标准的一对多关系:
class User
{
public int Id {get; set;}
// a user has zero or more bank accountTypes
public virtual ICollection<BankAccountType> BankAccountTypes {get; set;}
...
}
enum AcctType
{
single,
joint,
};
class BankAccountType
{
public int Id {get; set;}
// every bank account type belongs to one user via foreign key UserId:
public int UserId {get; set;}
public virtual User User {get; set;}
public AcctType AccType {get; set;}
public int AcctNo {get; set;}
}
您的查询分步骤:
var result = dbContext.BankAcctTypes
// Group all BankAcctTypes by the same UserId:
.GroupBy(bankAcctType => bankAcctType.UserId)
// From every group, get the Key (which is the UserId)
// get all elements of the group
// get a sequence of all joint accounts
.Select(group => new
{
UserId = group.Key, // the UserId of all bankAcctType in this group
AllBankAccounts = group,
JointBankAccounts = group
.Where(groupElement => groupElement.AccType == AcctType.Joint),
})
// if there are joint accounts, keep the joint accounts,
// otherwise keep AllAccounts (which are all Single, as there are no joint)
.Select(item => new
{
UserId = item.UserId,
BankAccounts = item.JointBankAccounts.Any() ?
item.JointBankAccount :
item.AllBankAccounts,
})
// finally extract the values you want:
.Select(item => new
{
UserId = item.UserId,
BankAccounts = item.BankAccounts.Select(bankAccount => new
{
Id = bankAccount.Id,
AcctType = bankAccount.AcctType,
AcctNo = bankAccount.AcctNo
}),
});