我们决定在最近的项目中使用Linq To SQL作为我们的数据层。我们有一个功能性的解决方案,到目前为止已经处理了我们所提出的所有问题,还有一个主要问题。我们必须反复编写相同的方法来从数据库中检索稍微不同的结果集。
举个例子:
public List<TeamBE> GetTeamsBySolutionID(Guid SolutionID)
{
List<TeamBE> teams = new List<TeamBE>();
Esadmin db = new Esadmin(_connectionString);
var qry = (from teamsTable in db.Teams
join solutionsTable in db.Solutions on teamsTable.SolutionID equals solutionsTable.SolutionID
where teamsTable.SolutionID == SolutionID
select new { teamsTable, solutionsTable.SolutionName });
foreach (var result in qry)
{
TeamBE team = new TeamBE();
team.TeamID = result.teamsTable.TeamID;
team.Description = result.teamsTable.Description;
team.Status = result.teamsTable.Status;
team.LastModified = result.teamsTable.LastModified;
team.SolutionID = result.teamsTable.SolutionID;
team.SolutionName = result.SolutionName;
team.Name = result.teamsTable.Name;
team.LocationLevel = result.teamsTable.LocationLevel;
team.AORDriven = result.teamsTable.AoRDriven;
team.CriteriaID = result.teamsTable.CriteriaID ?? Guid.Empty;
teams.Add(team);
}
return teams;
}
public TeamBE GetTeamByID(Guid TeamID)
{
Esadmin db = new Esadmin(_connectionString);
TeamBE team = new TeamBE();
var qry = (from teamsTable in db.Teams
join solutionsTable in db.Solutions on teamsTable.SolutionID equals solutionsTable.SolutionID
where teamsTable.TeamID == TeamID
select new { teamsTable, solutionsTable.SolutionName }).Single();
team.TeamID = qry.teamsTable.TeamID;
team.Description = qry.teamsTable.Description;
team.Status = qry.teamsTable.Status;
team.LastModified = qry.teamsTable.LastModified;
team.SolutionID = qry.teamsTable.SolutionID;
team.SolutionName = qry.SolutionName;
team.Name = qry.teamsTable.Name;
team.LocationLevel = qry.teamsTable.LocationLevel;
team.AORDriven = qry.teamsTable.AoRDriven;
team.CriteriaID = qry.teamsTable.CriteriaID ?? Guid.Empty;
return team;
}
并且持续恶作剧。
有没有办法将Linq结果作为参数传递给函数,所以我可以将对象映射放在一个函数中,而不是重复自己这么多?
答案 0 :(得分:2)
我快速刺了一下。可能不会编译(特别是“来自团队中的teamsTalbe”),但想法是你可以分解出返回IQueryable&lt;&gt;的东西。虽然IQueryable返回匿名类型,但这不起作用。所以你可能需要创建一个显式类型来代替'select new {teamsTable,solutionsTable.SolutionName}'
public List<TeamBE> GetTeamsBySolutionID(int solutionID)
{
Esadmin db = new Esadmin(_connectionString);
return GetTeamsBy(db, _GetTeamsBySolutionID(db, solutionID));
}
IQueryable<Team> _GetTeamsBySolutionID(Esadmin db, int solutionID)
{
return from teamsTable in db.Teams
where teamsTable.SolutionID == SolutionID
select teamsTable;
}
List<TeamBE> GetTeamsBy(Esadmin db, IQueryable<Team> teams)
{
List<TeamBE> teams = new List<TeamBE>();
var qry = (from teamsTable in teams
join solutionsTable in db.Solutions on teamsTable.SolutionID equals solutionsTable.SolutionID
select new { teamsTable, solutionsTable.SolutionName });
foreach (var result in qry)
{
TeamBE team = new TeamBE();
team.TeamID = result.teamsTable.TeamID;
team.Description = result.teamsTable.Description;
team.Status = result.teamsTable.Status;
team.LastModified = result.teamsTable.LastModified;
team.SolutionID = result.teamsTable.SolutionID;
team.SolutionName = result.SolutionName;
team.Name = result.teamsTable.Name;
team.LocationLevel = result.teamsTable.LocationLevel;
team.AORDriven = result.teamsTable.AoRDriven;
team.CriteriaID = result.teamsTable.CriteriaID ?? Guid.Empty;
teams.Add(team);
}
return teams;
}
答案 1 :(得分:1)
我认为您可以将qry
变量声明为IEnumerable<YourDataTypeEntity>
并将其传递给方法。我倾向于把它当作构造函数来做:
class MyDataType
{
public MyDataType() {}
public MyDataType(MyDataTypeEntity mdte)
{
// set properties and fields here
}
// ...
}
答案 2 :(得分:0)
你可以传递一个IQueryable然后当你想要处理结果然后你迭代结果。我不确定这是你要问的那种事情,还是我对你的问题不感兴趣。
答案 3 :(得分:0)
另请参阅AutoMapper,这是一种API,它使用基于约定的匹配算法来匹配对象中的源值与目标值。使用它可能会删除你的大部分a = b.c代码。
答案 4 :(得分:0)
我用entityFramework实现了这样的东西:
//This returns an IQueryable of your Linq2Sql entities, here you put your query.
protected IQueryable<Team> GetTeamByIdQuery(Guid teamID)
{
var qry = (from TeamsTable in db.Teams
where blablabla.....
select Teams;
return qry;
}
//This will return your real entity
public IList<TeamBE> GetTeamById(Guid teamID)
{
var query = this.GetTeamByIdQuery(teamID);
IList<TeamBE> teams = ExecuteTeamQuery(query).toList<TeamBE>();
return teams;
}
//this method will do the mapping from your L2S entities to your model entities
protected IQueryable<TeamBE> ExcuteTeamQuery(IQueryable<Team> query)
{
return
query.select<Team, TeamBE> (team =>
new TeamBE
{
TeamID = team.TeamID,
Description = team.Description
}
}
还没有测试这么多,但它确实有效。我还在研究如何根据bitflag参数定义要加载的属性。我还没有工作但是会像:
public IQueryable<TeamBE> ExcuteTeamQuery(IQueryable<Team> query, int loadLevel)
{
return
query.select<Team, TeamBE> (team =>
new TeamBE
{
TeamID = team.TeamID,
TeamMembers = (HaveToLoad(LoadLevel.TeamMembers, loadLevel)) ? team.TeamMembers : null
}
}
enter code here
答案 5 :(得分:0)
尝试扩展方法: 如果你有
public IQueryable<Team> GetTeams() { return db.Teams; }
尝试写作:
public IQueryable<Team> WithDivisionId(this IQueryable<Team> qry, int divisionId)
{ return (from t in qry where t.DivisionId = divisionId select t);}
通过这种方式,您可以编写多个扩展方法,可以查询任何IQueryable<Team>
并将它们分层......
要获得第1分区的队伍获得9分或更多胜利以及连胜5分或以上,您可以写下:
GetTeams().WithDivisionId(1).HavingWonAtLeast(9).WithWinningStreak(5);