我有以下方法,它在调用时接受 DataTime
参数并根据传递的日期返回记录。
方法:
public static void GetVehicleByReleasedDate(DateTime parameter)
{
using (EntityDataModel context = new EntityDataModel())
{
var query =
from vehicle in context.Catalog
where vehicle.ReleaseDate >= parameter.Date
select new
{
VehicleMake = vehicle.VehicleMake,
ManufactureID = vehicle.ManufactureID,
ManufactureDate = vehicle.ManufacturedDate,
VehicleIdentificationNumber = vehicle.VehicleIdentificationNumber
};
foreach (var vehicle in query)
{
Console.WriteLine("Format and write result to Console",
vehicle.ManufactureID,
vehicle.ManufactureDate,
vehicle.VehicleIdentificationNumber,
vehicle.VehicleMake);
}
}
}
我需要返回一个 IQueryable
对象或目录,而不是上面的内容,以便我可以在方法之外执行查询。
像这样:
public static IQueryable<Catalog> GetVehicleByReleasedDate()
{
using (EntityDataModel context = new EntityDataModel())
{
return context.Catalog;
}
}
然后像这样调用方法:
static void Main(string[] args)
{
var query = from vehicle in GetVehicleByReleasedDate()
where vehicle.ReleaseDate >= DateTime.Now
select new
{
VehicleMake = vehicle.VehicleMake,
ManufactureID = vehicle.ManufactureID,
ManufactureDate = vehicle.ManufacturedDate,
VehicleIdentificationNumber = vehicle.VehicleIdentificationNumber
};
foreach (var vehicle in query)
{
Console.WriteLine("{0} {1:d} {2} {3}",
vehicle.ManufactureID,
vehicle.ManufactureDate,
vehicle.VehicleIdentificationNumber,
vehicle.VehicleMake);
}
Console.ReadKey();
}
如您所知,我收到一个错误,因为 GetVehicleByReleasedDate()
中的 using 处理了上下文。
错误信息:
The operation cannot be completed because the DbContext has been disposed.
如何编写此代码,以便在释放 Context
之前,我可以简单地将查询从另一个使用返回类型的方法传递给该方法?
更新:
这是 EntityDataModel 类:
public partial class EntityDataModel : DbContext
{
public EntityDataModel()
: base("name=EntityDataModel")
{
}
public virtual DbSet<Catalog> Catalog { get; set; }
public virtual DbSet<Model> Model { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Catalog>()
.Property(e => e.VehicleIdentificationNumber)
.IsFixedLength();
}
}
最后,这是 Catalog 模型。
[Table("Automobile.Catalog")]
public partial class Catalog
{
[Key]
public long ManufactureID { get; set; }
[Required]
[StringLength(100)]
public string VehicleMake { get; set; }
[Required]
[StringLength(17)]
public string VehicleIdentificationNumber { get; set; }
[Column(TypeName = "date")]
public DateTime ManufacturedDate { get; set; }
[Column(TypeName = "date")]
public DateTime ReleaseDate { get; set; }
}
最佳答案
IQueryable 接口(interface)非常懒惰。它只在真正需要时才评估查询。我建议在查询结束时使用 .ToList() 来实现它:
var query =
(from vehicle in context.Catalog
where vehicle.ReleaseDate >= parameter.Date
select new
{
VehicleMake = vehicle.VehicleMake,
ManufactureID = vehicle.ManufactureID,
ManufactureDate = vehicle.ManufacturedDate,
VehicleIdentificationNumber = vehicle.VehicleIdentificationNumber
}).ToList();
否则,由于您的 using
语句,当 IQueryable 最终计算查询时上下文已经被释放。使用 ToList()
,您可以强制具体化查询,并将结果存储在内存中。
更新:正如 Gert Arnold 指出的那样,为了使答案更完整:
// YourStaticClass.cs
public static IEnumerable<Catalog> GetVehicleByReleasedDate(DateTime parameter)
{
using (var context = new EntityDataModel())
{
return context.Catalog
.Where(x => parameter.Date <= x.ReleaseDate)
.ToList();
}
}
// Main.cs
static void Main(string[] args)
{
var vehicles = YourStaticClass.GetVehicleByReleasedDate(DateTime.Today);
foreach (var vehicle in vehicles)
{
Console.WriteLine("{0} {1:d} {2} {3}",
vehicle.ManufactureID,
vehicle.ManufactureDate,
vehicle.VehicleIdentificationNumber,
vehicle.VehicleMake);
}
Console.ReadKey();
}
像这样,您可以在上下文仍“未处理”时具体化查询。您可以将数据吐出到任何需要的地方并进行处理。
关于c# - Entity Framework : How to query a model from other methods before DbContext is disposed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31775720/