带 LINQ 的最小起订量到实体投影

Moq with LINQ to entity projection

我正在尝试将 MOQ 集成到我的项目中,该项目利用 linq to entities - 并且在大多数情况下它按预期工作。我 运行 遇到的问题是当我投影到一个匿名对象时,该对象具有“SQLizer”可以处理的可为空的属性,但最小起订量抛出异常。

例如:

public class Person {
    public int Id {get;set;}
    public virtual void Car Car {get; set;}
}

public class Car {
   public int Id {get;set;}
}

public class Context {
   public DbSet<Car> Cars {get;set;}
   public DbSet<Person> People {get;set;}
}

// Just to show we have a person in the db without a car
context.People.Add(new Person{
   Id = 1,
});

// This throws an exception on MOQ, but works in SQL
context.People.Select(person => new {
   personId = person.Id,
   carId = (int?)person.Car.Id
});

我试图只强调我遇到的问题,也许不是最好的数据结构。关于如何处理这个的想法?最简单的方法是在投影之前检查空值,但我觉得可能有更好的选择。

当您使用上下文添加新的 Person 时,您似乎跳过添加 Car 实例并稍后尝试访问它:

context.People.Select(person => new {
   personId = person.Id,
   carId = (int?)person.Car.Id // above you instantiated a Person without a Car instance
});

这里发生的事情是,在新元素的投影过程中,Select 语句试图访问根本不存在的 Car 实例。

但是,如果您想要 Person 个不包含 Car 更改您的代码以匹配以下两种方法之一:

第一个选项(使用null-coalescing and null-conditional运算符)

context.People.Select(person => new {
   personId = person.Id,
   carId = person.Car?.Id ?? 0 // 0 is the default value in case if Person doesn't have Car
});

第二个选项使用过滤

context.People.Where(p => p.Car != null).Select(person => new {
   personId = person.Id,
   carId = person.Car.Id
});