我想计算相关表的行:
MainTable tbl = tblInfo(id);
var count = tbl.Related_Huge_Table_Data.Count();
问题是:执行时间太长(大约20秒),但是当我在Sql Server中运行此查询时,执行时间不到一秒。如何在linq中优化此查询?我也试过使用存储过程,但没有运气。
这是tblInfo
方法:
public MainTable tblInfo(int id)
{
MyDataContext context = new MyDataContext();
MainTable mt = (from c in context.MainTables
where c.Id == id
select c).SingleOrDefault();
return mt;
}
我使用了LinqToSql,类是由LinqToSql生成的。
答案 0 :(得分:9)
通过运行SingleOrDefault()
,您执行查询并在此之后必须处理内存中的结果。您需要使用IQueryable
,直到查询完全构建完毕。
回答“此父记录有多少个子记录”的最简单方法是从子方面接近它:
using (var dx = new MyDataContext())
{
// If you have an association between the tables defined in the context
int count = dx.Related_Huge_Table_Datas.Where(t => t.MainTable.id == 42).Count();
// If you don't
int count = dx.Related_Huge_Table_Datas.Where(t => t.parent_id == 42).Count();
}
如果你坚持父方方法,你也可以这样做:
using (var dx = new MyDataContext())
{
int count = dx.MainTables.Where(t => t.id == 42).SelectMany(t => t.Related_Huge_Table_Datas).Count();
}
如果你想在tblInfo
这样的函数中保留这个查询的一部分,你可以,但你不能从这个函数内部实例化MyDataContext
,否则你会在尝试时遇到异常将查询与MyDataContext
的另一个实例一起使用。因此,要么将MyDataContext
传递给tblInfo
,要么让tblInfo
成为partial class MyDataContext
的成员:
public static IQueryable<MainTable> tblInfo(MyDataContext dx, int id)
{
return dx.MainTables.Where(t => t.id == id);
}
...
using (var dx = new MyDataContext())
{
int count = tblInfo(dx, 42).SelectMany(t => t.Related_Huge_Table_Datas).Count();
}
答案 1 :(得分:2)
试试这个
//Bank Account class
import java.text.NumberFormat;
public class BankAccount {
private String ownerName;
private String accountId;
private double accountBalance;
public BankAccount(String ownerName, String accountId, double accountBalance) {
this.ownerName = ownerName;
this.accountId = accountId;
if(accountBalance >= 0) {
this.accountBalance = accountBalance;
} else {
System.out.println("Due to your negative account balace, you will be issued a fee.\n");
}
}
public BankAccount(double accountBalance) {
accountBalance = 0;
}
public String getOwnerName() {
return ownerName;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(double accountBalance) {
if(accountBalance >= 0) {
this.accountBalance = accountBalance;
} else {
System.out.println("Due to your negative account balace, you will be issued a fee.\n");
}
}
public void withdraw(double amount) {
if(amount > 0 && amount < accountBalance) {
accountBalance -= amount;
} else {
System.out.println("Invalid withdraw amount! Please try again.\n");
}
}
public void deposit(double amount) {
if(amount > 0) {
accountBalance += amount;
} else {
System.out.println("Invalid deposit amount! Please try again.\n");
}
}
public String toString() {
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
return "Account Owner's Name: " + ownerName + "\n" + "Account ID: " + accountId + "\n" +
"Balance in the account: " + currencyFormatter.format(accountBalance);
}
}
//Driver Program
public class BankAccountDriver {
public static void main(String[] args) {
BankAccount myAccount = new BankAccount("Smith", "123jahgsd", 1200);
myAccount.withdraw(0.453);
myAccount.deposit(1000.1);
System.out.println(myAccount);
}
}
答案 2 :(得分:1)
如果您希望充分利用SQL数据库的性能,直接查询它而不是使用Linq可能是有意义的。应该更合理地执行:)
var Related_Huge_Table_Data = "TABLENAME";//Input table name here
var Id = "ID"; //Input Id name here
var connectionString = "user id=USERNAME; password=PASSWORD server=SERVERNAME; Trusted_Connection=YESORNO; database=DATABASE; connection timeout=30";
SqlCommand sCommand = new SqlCommand();
sCommand.Connection = new SqlConnection(connectionString);
sCommand.CommandType = CommandType.Text;
sCommand.CommandText = $"COUNT(*) FROM {Related_Huge_Table_Name} WHERE Id={ID}";
sCommand.Connection.Open();
SqlDataReader reader = sCommand.ExecuteReader();
var count = 0;
if (reader.HasRows)
{
reader.Read();
count = reader.GetInt32(0);
}
else
{
Debug.WriteLine("Related_Huge_Table_Data: No Rows returned in Query.");
}
sCommand.Connection.Close();
答案 3 :(得分:0)
试试这个:
MyDataContext context = new MyDataContext();
var count = context.MainTables.GroupBy(x => x.ID).Distict().Count();
答案 4 :(得分:0)
在许多情况下,GSerg的答案是正确的。但是当你的表开始变得非常大时,即使SQL Server中的width=840
也很慢。
最好的解决方法是直接查询数据库统计信息,这对Linq来说是不可能的(或者我不知道)。
您可以做的最好的事情是在表定义上创建一个静态子(C#),它将返回以下查询的结果:
height=1188
其中Count(1)
是表格的数据库名称。
请注意,这只是对计算表中所有记录的情况的答案!
答案 5 :(得分:0)
您的linq2sql是否返回记录集然后在本地执行.Count(),还是将SQL发送到服务器以在服务器上进行计数?那里的表现会有很大差异。
另外,您是否检查了执行查询时生成的SQL?从内存中,Linq2Sql允许您检查SQL(可能是通过在您的类上设置记录器?)。在Entity Framework中,您可以在调试和检查IQueryable&lt;&gt;时看到它。对象,不确定Linq2Sql中是否有等价物。
Way to view SQL executed by LINQ in Visual Studio?
或者,使用SQL Server Profiler(如果可用),或以某种方式查看正在执行的内容。
答案 6 :(得分:0)
您可以尝试以下操作: -
var c = from rt in context.Related_Huge_Table_Data
join t in context.MainTables
on rt.MainTableId ==t.id where t.id=id
select new {rt.id};
var count=c.Distict().Count();