c# - Entity Framework : How to query a model from other methods before DbContext is disposed?

标签 c# linq entity-framework

我有以下方法,它在调用时接受 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/

相关文章:

entity-framework - group by 之后返回 List<string>

c# - 无法在 Visual Studio 2010 中为简单的 dll 类创建类图

c# - Page.ClientScript.RegisterStartupScript 第二次不显示消息

c# - Linq to SQL Where In子句导致对象未设置为对象实例

c# - 接口(interface)实现应该如何处理调用者可能期望的类型的意外内部异常?

C# 使用 linq 查找匹配两个元素级别的 xml 元素

linq - 将 IEqualityComparer 与 LINQ to Entities except 子句结合使用

sql - 如何构建正确的 LINQ 查询(生成 OR 而不是 AND)

c# - 将 Entity Framework 6 与 MySQL 结合使用

entity-framework - Entity Framework : Sharing entities across different DbContexts