代码首先一对一选择查询

时间:2013-12-15 15:23:53

标签: c# linq ef-code-first one-to-one

我尝试使用Code First但我遇到了一些麻烦,我想我忘了或错过了什么...... 我有两个非常简单的模型:(一辆车有一个FuelType,它是一对一的关系)

public class Car
{
    public int CarID { get; set; }
    public string CarName { get; set; }
    public Fuel FuelType { get; set; }
    ...
}
public class Fuel
{
    public int FuelID { get; set; }
    public string Name{ get; set; }
    ...
}

我的contextClass:

public class CarDbContext : DbContext
{
    public DbSet<Car> Cars { get; set; }
    public DbSet<Fuel> Fuels { get; set; }

    public CarDbContext()
        : base("CarDbConnectionString")
    {
        Database.SetInitializer<CarDbContext>(new CreateDatabaseIfNotExists<CarDbContext>());
    }

我的主要计划:

class Program
{
    static void Main(string[] args)
    {
        IList<Car> maListe;

        using (var ctx = new CarDbContext())
        {
            var car = from c in ctx.Cars
                          select c;

            maListe = car.ToList<Car>();
        }

        foreach (Car c in maListe)
            Console.WriteLine("Car: {0} {1}", c.CarName, c.FuelType.Name);

        Console.ReadLine();
    }
}

在我的控制台中,我可以看到CarName但不能看到汽车的FuelType.Name。

我尝试了一些事情,例如将我的查询更改为:

  var car = from c in ctx.Cars.Include("Fuels")
            select c;

但我得到一个例外:

  

指定的包含路径无效。实体类型“Car”未声明名为“Fuels”

的导航属性

有人可以向我解释我做错了什么或忘记了什么吗?

4 个答案:

答案 0 :(得分:1)

您有名为FuelType的导航属性:

var cars = ctx.Cars.Include("FuelType"); // not `Fuels`

答案 1 :(得分:1)

如果您想'急切加载'FuelType,请尝试:

var car = from c in ctx.Cars.Include("FuelType")

或者,您可以将其标记为virtual,并为您FuelType'延迟加载':

public class Car
{
    public int CarID { get; set; }
    public string CarName { get; set; }
    public virtual Fuel FuelType { get; set; }
    ...
}

答案 2 :(得分:1)

你确定它是一对一的关系吗? FuelType只与一辆车相关联?

无论如何,为了建立一对一关系,您必须在您的从属实体中包含Principal实体的导航属性,如下所示:

public class CarDbContext : DbContext
{
    public CarDbContext()
        : base("CarDbConnectionString")
    {
        Database.SetInitializer<CarDbContext>(new CreateDatabaseIfNotExists<CarDbContext>());
    }

    public DbSet<Car> Cars { get; set; }
    public DbSet<Fuel> Fuels { get; set; }
}

public class Car
{
    [Key]
    public int CarID { get; set; }
    public string CarName { get; set; }
    public virtual Fuel FuelType { get; set; }    // set as virtual
}

public class Fuel
{
    [Key, ForeignKey("Car")]                      // primary and foreign key
    public int FuelID { get; set; }
    public string Name { get; set; }
    public virtual Car Car { get; set; }          // must include a navigation property for the Principal entity
}

但如果是一对多关系,您可以按照以下方式处理:

public class Car
{
    [Key]
    public int CarID { get; set; }
    public string CarName { get; set; }
    public int FuelTypeID { get; set; }
    [ForeignKey("FuelTypeID")]
    public virtual Fuel FuelType { get; set; }
}

public class Fuel
{
    public int FuelID { get; set; }
    public string Name { get; set; }
}

public class CarDbContext : DbContext
{
    public CarDbContext()
        : base("CarDbConnectionString")
    {
        Database.SetInitializer<CarDbContext>(new CreateDatabaseIfNotExists<CarDbContext>());
    }

    public DbSet<Car> Cars { get; set; }
    public DbSet<Fuel> Fuels { get; set; }
}

答案 3 :(得分:0)

感谢大家回答我 你的答案确实让我在EF理解方面取得了进步 顺便说一下,我真的遇到了“System.Reflection.TargetInvocationException”异常 我在代码中改变了很多东西,而不是现在它有效但不幸的是我无法理解为什么:(