问题
I am using the Entity Framework to access my database and I just figured out that mapping stored procedures to methods using entity is a bit too complex and probably not well suited to do what I want exacltly. I am new to LINQ and I am wondering if I sould be better off just with ADO.NET. Here is the SQL code I need to translate:
SELECT p.Player_id, p.Name, p.Position, SUM(s.Goals) AS goalsb, SUM(s.Assists) AS assistsb, SUM(s.Points) AS pointsb
FROM Dim_Player AS p INNER JOIN Fact_Statistics AS s ON s.Player_id = p.Player_id
GROUP BY p.Player_id, p.Name, p.Position
ORDER BY pointsb DESC, goalsb DESC
With the Entities mapping for stored procedures, I had this code written:
HockeyStatsEntities db = new HockeyStatsEntities();
public ActionResult Index()
{
ViewBag.Message = "League leaders";
{
return View(db.ListLeagueLeaders());
}
}
public ActionResult About()
{
return View();
}
private ICollection<ListLeagueLeaders_Result> ListLeagueLeaders()
{
ICollection<ListLeagueLeaders_Result> leagueLeadersCollection = null;
using (HockeyStatsEntities context = new HockeyStatsEntities())
{
foreach (ListLeagueLeaders_Result leagueLeader in
context.ListLeagueLeaders())
{
leagueLeadersCollection.Add(leagueLeader);
}
}
return leagueLeadersCollection;
}
Here is the error I am getting:
The model item passed into the dictionary is of type 'System.Data.Objects.ObjectResult`1[NHLStats2.Models.ListLeagueLeaders_Result]', but this dictionary requires a model item of type 'NHLStats2.Models.ListLeagueLeaders_Result'.
But I realize that this is a bit of a pain in the ?&*@... How could I re-arrange this using a different, more effective method? Thanks for your help, it's really appreciated.
回答1:
You can write a simple LINQ query, using a model with these 2 tables, keeping their relationship:
from p in ctx.Dim_Player
select new {p.Player_id, p.Name, Goals = p.Fact_Statstics.Select(x=>(int?)x.Goals).Sum()}
You Dim_Player will have a FactStatistics property with the related statistics. You can apply subqueries with the SUMs and COUNTs you want.
The query above is returning an anonymous type, but you can create a class with the desired properties.
It's important to use the (int?) cast.
回答2:
Finally opting for using a stored procedure, this compiles and works:
Model1.tt.Context.cs (autogenerated)
public DbSet<Dim_Date> Dim_Date { get; set; }
public DbSet<Dim_Player> Dim_Player { get; set; }
public DbSet<Dim_Team> Dim_Team { get; set; }
public DbSet<Fact_Statistics> Fact_Statistics { get; set; }
public DbSet<Dim_Game> Dim_Game { get; set; }
public virtual ObjectResult<ListLeagueLeaders_Result> ListLeagueLeaders()
{
((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace.LoadFromAssembly(typeof(ListLeagueLeaders_Result).Assembly);
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<ListLeagueLeaders_Result>("ListLeagueLeaders");
}
View
@model System.Data.Objects.ObjectResult<NHLStats2.Models.ListLeagueLeaders_Result>
@{
ViewBag.Title = "Index";
}
[...]
Problem was with the strongly typed view type not matching the System.Data.Objects.ObjectResult type. Was: @model NHLStats2.Models.ListLeagueLeaders_Result, changed to: @model System.Data.Objects.ObjectResult<NHLStats2.Models.ListLeagueLeaders_Result> Cheers!
来源:https://stackoverflow.com/questions/8543261/linq-to-entities-instead-of-stored-procedure