我有一个项目的简单评级应用程序。主要有三个表:
Item
{
ItemID,
Contents
}
asp_User
{
UserID,
Name
}
Rating
{
RatingID,
ItemID,
UserID,
int Rating
}
我有读取项目的linq代码:
var q = from item db.Item
select item;
然后,我想在q后面附加一个列,其中包含当前经过身份验证的用户的每个项目行的评级。如果用户未登录或经过身份验证的用户未提供评级,则结果将为0.
如果重要的话,我正在使用SqlMembershipProvider。
实施例
q的最终结果应如下所示:
[认证]
//The currently authenticated user has commented on Item.ID = 1 and has given it a 9.
q = {ID = 1, Contents = "Whatever", Rating = 9},
//The currently Authenticated user has not commented on Item.ID = 2.
{ID = 2, Contents = "Something", Rating = 0};
[未经过身份验证]
//There is not an authenticated user
q = {ID = 1, Contents = "Whatever", Rating = 0},
//There is not an authenticated user
{ID = 2, Contents = "Something", Rating = 0};
答案 0 :(得分:0)
你打算用“var q”做什么?很难说出你的意图是什么,在这种情况下它很重要。基于缺乏背景,这是我能做的最好的事情。希望这会有所帮助:
if(User.IsAuthenticated)
{
var q = from item in db.Item
join r in db.Rating on c.Id equals r.ItemId
select new {ID = item.Id, Contents = item.Contents, Rating = r.Rating};
// Do whatever you want with this here.
}
else
{
var y = db.Item;
// Do whatever you want with this here.
}
答案 1 :(得分:0)
从性能角度来看,Ocelots解决方案是可行的方法(特别是如果您查询多个项目)。 但是为了满足Rating应该是Item的属性的条件,您可以通过在LINQ-to-SQL数据类的同一名称空间中使用部分类来扩展Item类:
public partial class Item
{
public int Rating
{
get
{
if (!Thread.CurrentPrincipal.Identity.IsAuthenticated)
return 0;
using (var db = new ApplicationDataContext())
{
return db.Item
.Where(r => r.ItemID == this.ItemID
&& r.UserID == Thread.CurrentPrincipal.Identity.Name)
.Select(r => r.Rating)
.SingleOrDefault();
}
}
}
}
如果你想用像Ocelot提出的单个SQL请求得到相同的结果,你应该使用GroupJoin(就像SQL LEFT OUTER JOIN一样工作)并选择当前的用户评级,如上所述。