尝试键入包含两个表中信息的Linq表达式。
var articles = db.Articles;
var articlescores = db.ArticleScores;
文章表有标题字段
articles.title
articlescores表具有ActualCity字段和ArticleID字段
articlescores.ActualCity
artickescores.ArticleID (which links to articles table)
我需要.Count()
articlescores.ActualCity
字段,然后将最高计数的城市与articles.title
基本上是一个城市观看的文章。
示例数据:
ArticleScore表:
ID articleID City (Note: articleID is not dependent on City, I just wrote it this way)
1 1 New York
2 2 Boston
3 1 New York
4 1 New York
5 1 New York
6 2 Boston
文章表:
ID title
1 TitleOneOfArticles
2 TitleTwoOfArticles
预期输出(因为纽约有4个,波士顿只有2个):
TitleOneOfArticles, NewYork(4)
^^ ^^ ^
title City Count
预计只有一行输出。
答案 0 :(得分:3)
你的问题是自相矛盾的,而且它也缺少一些关键信息。所以我要猜一猜。
以下是我对ArticleScore数据集示例的理解:
ID articleID City
? 1 New York
? 1 New York
? 1 New York
? 1 Boston
? 2 New York
? 2 Boston
? 2 Boston
在这个数据集中,NewYork的第1条有3个视图,第2条有1个视图。同样,在波士顿,有2篇关于第2条的视图和1条关于第1条的视图。
根据这些数据,我假设你想得到类似的东西
TitleTwoOfArticles, Boston(2)
TitleOneOfArticles, NewYork(3)
上表显示在波士顿,观看次数最多的文章是第2条,总共有2个观看次数。在NewYork,观看次数最多的文章是1,总共3个视图。请注意,此处未显示所有城市中文章的总观看次数。
创建了一个代码示例来测试上面的场景,因为我使用了它:
以下是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
namespace SO22928136
{
public interface IMyDbContext : IDisposable
{
IDbSet<Article> Articles { get; set; }
IDbSet<ArticleScore> ArticleScores { get; set; }
int SaveChanges();
}
public class MyDbContext : DbContext, IMyDbContext
{
public IDbSet<Article> Articles { get; set; }
public IDbSet<ArticleScore> ArticleScores { get; set; }
static MyDbContext()
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
}
public MyDbContext(string connectionString) : base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new ArticleConfiguration());
modelBuilder.Configurations.Add(new ArticleScoreConfiguration());
}
}
public class Article
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<ArticleScore> ArticleScores { get; set; }
public Article()
{
ArticleScores = new List<ArticleScore>();
}
}
public class ArticleScore
{
public int Id { get; set; }
public int ArticleId { get; set; }
public string ActualCity { get; set; }
public virtual Article Article { get; set; }
}
internal class ArticleConfiguration : EntityTypeConfiguration<Article>
{
public ArticleConfiguration()
{
ToTable("Article");
HasKey(x => x.Id);
Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Title).HasColumnName("Title").IsOptional();
}
}
internal class ArticleScoreConfiguration : EntityTypeConfiguration<ArticleScore>
{
public ArticleScoreConfiguration()
{
ToTable("ArticleScore");
HasKey(x => x.Id);
Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.ArticleId).HasColumnName("ArticleId").IsRequired();
Property(x => x.ActualCity).HasColumnName("ActualCity").IsOptional().HasMaxLength(10);
HasRequired(a => a.Article).WithMany(b => b.ArticleScores).HasForeignKey(c => c.ArticleId);
}
}
class Program
{
static void Main()
{
MyDbContext context = new MyDbContext("Data Source=(local);Initial Catalog=SO22928136;Integrated Security=True;");
CreateTestData(context);
var countOfArticlesPerCity = context.ArticleScores.GroupBy(s => new {s.ArticleId, s.ActualCity}).Select(g => new {g.Key.ArticleId, g.Key.ActualCity, Count = g.Count()});
var highestArticleCountPerCity = countOfArticlesPerCity.GroupBy(x => x.ActualCity).Select(g => g.OrderByDescending(x => x.Count).FirstOrDefault());
var highestArticleCountPerCityWithArticleTitle = context.Articles.Join(highestArticleCountPerCity, x => x.Id, p => p.ArticleId, (x, p) => new { x.Title, p.ActualCity, p.Count });
foreach (var line in highestArticleCountPerCityWithArticleTitle)
{
Console.WriteLine("{0}, {1}({2})",line.Title,line.ActualCity, line.Count);
}
}
private static void CreateTestData(MyDbContext context)
{
Article articleOne = new Article { Title = "TitleOneOfArticles" };
Article articleTwo = new Article { Title = "TitleTwoOfArticles" };
articleOne.ArticleScores.Add(new ArticleScore { ActualCity = "NewYork" });
articleOne.ArticleScores.Add(new ArticleScore { ActualCity = "NewYork" });
articleOne.ArticleScores.Add(new ArticleScore { ActualCity = "NewYork" });
articleOne.ArticleScores.Add(new ArticleScore { ActualCity = "Boston" });
articleTwo.ArticleScores.Add(new ArticleScore { ActualCity = "NewYork" });
articleTwo.ArticleScores.Add(new ArticleScore { ActualCity = "Boston" });
articleTwo.ArticleScores.Add(new ArticleScore { ActualCity = "Boston" });
context.Articles.Add(articleOne);
context.Articles.Add(articleTwo);
context.SaveChanges();
}
}
}
您最感兴趣的linq查询是主要方法。修改连接字符串以指向测试服务器。确保您使用的数据库名称不存在,因为具有此名称的数据库将被删除。小心。
程序运行时,它会删除/创建指定的数据库并在其中创建示例模式。如上所述,它继续插入其样本数据。然后是您感兴趣的实际查询。
我将查询分为三部分。首先,我们按城市名称和文章ID进行分组,并计算每行的计数。其次,我们只选择每个城市拥有最大计数的那些行。最后,我们加入Article表,从id获取文章标题。
之后我们打印出结果。应该很容易修改查询只返回一行,你只需要为它添加一个条件。
答案 1 :(得分:-1)
试试这个linq:
db.Articles
.Join(db.ArticleScores ,
art=> art.ID,
scr=> scr.ID,
(art, scr) => new { article= art, score= scr})
.Where(both => (both.art.ID == cityID))
.Select(both => both.score)
cityId是您应该发送的参数