Sql server LINQ到具有左连接的实体
我已经以原始SQL的形式对数据库进行了查询,并希望将SQL转换为实体 其原因是,性能在其构造方式上非常糟糕,而不是实际的快速查询,但之后我不得不执行多个SQL语句以从关联表中获取数据。我在想,如果我将SQL迁移到实体,那么关联的表已经被获取,我只需要对数据库进行一次调用 我像这样构造我的旧查询:Sql server LINQ到具有左连接的实体,sql-server,entity-framework,Sql Server,Entity Framework,我已经以原始SQL的形式对数据库进行了查询,并希望将SQL转换为实体 其原因是,性能在其构造方式上非常糟糕,而不是实际的快速查询,但之后我不得不执行多个SQL语句以从关联表中获取数据。我在想,如果我将SQL迁移到实体,那么关联的表已经被获取,我只需要对数据库进行一次调用 我像这样构造我的旧查询: List<Database.Product> products = null; string sql = "SELECT P.* FROM Product p " +
List<Database.Product> products = null;
string sql = "SELECT P.* FROM Product p " +
"LEFT JOIN ProductAssigned pa ON pa.ProductId = p.Id " +
"WHERE pa.UserId = @userid AND pa.UnassignedAt IS NULL";
sql = FilterByProductState(productFilter, sql);
if (startDate != default && endDate != default)
{
string start = startDate.Year + "/" + startDate.Month + "/" + startDate.Day;
string end = endDate.Year + "/" + endDate.Month + "/" + endDate.AddDays(1).Day;
sql += " AND (p.StartAt BETWEEN '" + start + "' AND '" + end + "' OR p.CompleteAt BETWEEN '" + start + "' AND '" + end + "')";
}
List<SqlParameter> sqlParameters = new List<SqlParameter>
{
new SqlParameter("@userid", userId)
};
sql += " ORDER BY p.StartAt";
try
{
products = context.Database.SqlQuery<Database.Product>(sql, new SqlParameter("@userid", userId)).ToList();
}
catch (Exception e)
{
throw;
}
在这之后,就像我说的,我必须去获取一些相关的表
我尝试过几件事,例如使用GroupJoin,但似乎没有成功。此外,我正在动态创建SQL语句,所以我甚至不知道它是否可以在SQL to实体中工作
更新:
产品(有趣的部分)和产品分配如下所示:
public partial class Product
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Product()
{
this.ProductAssigned = new HashSet<ProductAssigned>();
}
public int Id { get; set; }
public string Name { get; set; }
public Nullable<System.DateTime> StartAt { get; set; }
public Nullable<System.DateTime> CompleteAt { get; set; }
public Nullable<System.DateTime> DeletedAt { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ProductAssigned> ProductAssigned { get; set; }
}
public partial class ProductAssigned
{
public int Id { get; set; }
public int ProductId { get; set; }
public int UserId { get; set; }
public System.DateTime AssignedAt { get; set; }
public Nullable<System.DateTime> UnassignedAt { get; set; }
public virtual Product Product { get; set; }
public virtual User CreatedByUser { get; set; }
public virtual User DeletedByUser { get; set; }
public virtual User UserAssigned { get; set; }
}
公共部分类乘积
{
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2214:DoNotCallOverridableMethodsInConstructors”)]
公共产品()
{
this.ProductAssigned=new HashSet();
}
公共int Id{get;set;}
公共字符串名称{get;set;}
公共可为空的StartAt{get;set;}
公共可为空的CompleteAt{get;set;}
公共可为空的DeletedAt{get;set;}
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2227:CollectionPropertiesShouldBreadOnly”)]
公共虚拟ICollection ProductAssigned{get;set;}
}
公共部分类
{
公共int Id{get;set;}
public int ProductId{get;set;}
public int UserId{get;set;}
public System.DateTime AssignedAt{get;set;}
公共可为null的未分配数据{get;set;}
公共虚拟产品产品{get;set;}
公共虚拟用户CreatedByUser{get;set;}
公共虚拟用户DeletedByUser{get;set;}
公共虚拟用户用户分配{get;set;}
}
LINQ查询可以以非常类似的方式构建。在EF查询中,您可以考虑对象、引用和集合,而不是手动联接,EF将其转换为必要的联接
第一部分可以完全按照SQL查询编写
IQueryable查询=
来自context.Products中的p
从p.ProductAssigned.DefaultIfEmpty()中的pa开始//这应该很容易在L2E中构建,特别是如果您的模型具有正确的导航属性(应该是这样的)。为了提供帮助,我们需要查看产品
和产品分类
类,因此请将它们包括在问题中。@IvanStoev您好,我已经将这些类包括在描述中,效果非常好!非常感谢你学会了如何处理这件事。获取对象需要将近一半的时间。
public partial class Product
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Product()
{
this.ProductAssigned = new HashSet<ProductAssigned>();
}
public int Id { get; set; }
public string Name { get; set; }
public Nullable<System.DateTime> StartAt { get; set; }
public Nullable<System.DateTime> CompleteAt { get; set; }
public Nullable<System.DateTime> DeletedAt { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ProductAssigned> ProductAssigned { get; set; }
}
public partial class ProductAssigned
{
public int Id { get; set; }
public int ProductId { get; set; }
public int UserId { get; set; }
public System.DateTime AssignedAt { get; set; }
public Nullable<System.DateTime> UnassignedAt { get; set; }
public virtual Product Product { get; set; }
public virtual User CreatedByUser { get; set; }
public virtual User DeletedByUser { get; set; }
public virtual User UserAssigned { get; set; }
}