我在库中有一个 DbContext 以及实体及其在 fluent api 中的配置。
我在两个不同的项目中使用相同的上下文。第一个是测试项目,第二个是简单的控制台应用程序。
我执行一个查询,包括它的一些关系,如下所示:
var vacancies = (from v in ctx.Vacancies
.Include("Categories")
.Include("Levels")
.Include("Contracts")
.Include("JobTypes"));
奇怪的是,控制台应用程序运行良好,但是单元测试突然开始在错误的表中查找。
当我查看它们时,这两个应用程序都会产生非常不同的查询。
我正在使用 EF5 自动取款机,我已经坚持了几天了,对可能导致此问题的原因一无所知。
编辑:关键是我没有做任何不同的查询,我也只有上下文,只有一个我在运行时确认的连接字符串连接到正确的数据库。
我只能说,我觉得流利的 api 在单元测试中没有任何影响,即使它像它应该的那样很好地命中了代码。
public class SchedulerContext : BaseContext<SchedulerContext>{
public DbSet<Click> Clicks { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<ContractType> Contracts { get; set; }
public DbSet<JobType> JobTypes { get; set; }
public DbSet<Level> Levels { get; set; }
public DbSet<ExternalMapping> ExternalMappings { get; set; }
public DbSet<GeoName> GeoNames { get; set; }
public DbSet<GeoAlternateName> GeoAlternateNames { get; set; }
public DbSet<Trigger> JobTriggers { get; set; }
public DbSet<RegistryValue> RegistryValues { get; set; }
public DbSet<JobResult> JobResults { get; set; }
public DbSet<JobInfo> JobInfo { get; set; }
public DbSet<JobError> JobErrors { get; set; }
public DbSet<JobNotification> JobNotifications { get; set; }
public DbSet<Company> Customers { get; set; }
public DbSet<Vacancy> Vacancies { get; set; }
public SchedulerContext() {
//this.Configuration.ProxyCreationEnabled = false;
//this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Configurations.Add(new VacancyEntityTypeConfiguration());
base.OnModelCreating(modelBuilder);
}
}
这就是我的背景。
还有我的实体配置:
public class VacancyEntityTypeConfiguration : EntityTypeConfiguration<Vacancy> {
public VacancyEntityTypeConfiguration() {
this.HasMany(c => c.Levels).
WithMany().
Map(
m => {
m.ToTable("VacancyLevels");
});
this.HasMany(c => c.Categories).
WithMany().
Map(
m => {
m.ToTable("VacancyCategories");
});
this.HasMany(c => c.Contracts).
WithMany().
Map(
m => {
m.ToTable("VacancyContractTypes");
});
this.HasMany(c => c.Jobtypes).
WithMany().
Map(
m => {
m.ToTable("VacancyJobTypes");
});
}
}
以及显示问题的确切方法。
public List<Vacancy> GetVacanciesForCustomer(Company customer, bool onlineInclusive) {
using (var ctx = new JHSchedulerContext.SchedulerContext()) {
var vacancies = (from v in ctx.Vacancies.Include("Categories").Include("Levels").Include("Contracts").Include("JobTypes") where v.SourceSite == customer.SourceSite && (v.Online || onlineInclusive == false) select v).ToList();
return vacancies.ToList();
}
}
和空缺班:
public class Vacancy {
public Vacancy()
{
this.Language = "";
}
[SolrUniqueKey("id")]
[Key]
[Required]
public int Id { get; set; }
[StringLength(50, ErrorMessage = "Maximum length 50 characters")]
public string ExternalId { get; set; }
[SolrField("title")]
[StringLength(1024, ErrorMessage = "Maximum length 1024 characters")]
public string Title { get; set; }
[SolrField("company")]
[StringLength(1024, ErrorMessage = "Maximum length 1024 characters")]
public string Company { get; set; }
[StringLength(4096, ErrorMessage = "Maximum length 4096 characters")]
public string CompanyText { get; set; }
[SolrField("location")]
[StringLength(1024, ErrorMessage = "Maximum length 1024 characters")]
public string Location { get; set; }
[SolrField("url")]
[StringLength(1024, ErrorMessage = "Maximum length 1024 characters")]
public string Url { get; set;}
[SolrField("source")]
[StringLength(1024, ErrorMessage = "Maximum length 1024 characters")]
public string SourceSite { get; set; }
private string text;
[SolrField("text")]
[StringLength(4096, ErrorMessage = "Maximum length 4096 characters")]
public string Text {
get {
return StringHelper.TruncateAtWord(text, 500);
//return new String(text.Take(500).ToArray());
//return text.Substring(text.Length < 900 ? 0 : (text.Length / 2), (int)Math.Min(text.Length, 500));
}
set{
text = value;
}
}
[StringLength(4096, ErrorMessage = "Maximum length 4096 characters")]
public string TextProfile { get; set; }
[StringLength(4096, ErrorMessage = "Maximum length 4096 characters")]
public string TextOffer { get; set; }
[NotMapped]
[ScriptIgnore]
public SqlGeography Coordinate {
get
{
if (Latitude.HasValue && Longitude.HasValue)
return SqlGeography.Point(Latitude.Value, Longitude.Value, 4326);
else
return null;
}
}
[SolrField("coordinate_0_coordinate")]
public double? Latitude { get; set; }
[SolrField("coordinate_1_coordinate")]
public double? Longitude { get; set; }
[StringLength(1024, ErrorMessage = "Maximum length 1024 characters")]
public string NormalizedLocation { get; set; }
public DateTime? ScrapedDate { get; set; }
[SolrField("insertdate")]
public DateTime? ImportDate { get; set; }
public DateTime? ExpireDate { get; set; }
[NotMapped]
public string DaysAgo {
get {
if (ImportDate != null)
return (DateTime.Now - (DateTime)ImportDate).Days.ToString();
else {
return "N/A";
}
}
}
[SolrField("category")]
public ICollection<string> CategoryNames {
get { return Categories != null ? Categories.Select(c => c.Name).ToList() : null; }
}
[SolrField("level")]
public ICollection<string> LevelNames {
get { return Levels != null ? Levels.Select(l => l.Name).ToList() : null; }
}
[SolrField("contract")]
public ICollection<string> ContractNames {
get { return Contracts != null ? Contracts.Select(c => c.Name).ToList() : null; }
}
[SolrField("time")]
public ICollection<string> JobTypeNames {
get { return Jobtypes != null ? Jobtypes.Select(c => c.Name).ToList() : null; }
}
public string ContactName { get; set; }
[Required]
public bool Online { get; set; }
[NotMapped]
public int? Distance { get; set; }
public string Language { get; set; }
public string PriorityType { get; set; }
public int NumClicks { get; set; }
[NotMapped]
public string GridContactName {
get{
return string.Format("{0} (Total Clicks:{1})",ContactName,NumClicks);
}
}
public virtual ICollection<Level> Levels { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<ContractType> Contracts { get; set; }
public virtual ICollection<JobType> Jobtypes { get; set; }
public override string ToString() {
return string.Format("Id={0} ExternalId={1} Title={2} Company={3} Location={4} Url={5} SourceSite={6} Text={7} NormalizedLocation={8} InsertDate={9} ImportDate={10} DaysAgo={11}",Id, ExternalId,Title,Company,Location,Url, SourceSite,Text,NormalizedLocation,ScrapedDate,ImportDate,DaysAgo);
}
}
和级别类(所有其他关系类具有相同的结构(名称,id):
public class Level {
[Key]
[Required]
public int Id { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Maximum length 100 characters")]
public string Name { get; set; }
public override string ToString() {
return string.Format("Id={0} Name={1}", Id, Name);
}
}
就与数据库的连接而言,您只需要相信我已经检查过两者都连接到同一个数据库。(我什至生成了一个启用迁移的新数据库,因为我们使用另一个上下文进行迁移。那仍然有完全相同的问题)。
澄清一下:单元测试查找表:CategoryVacancys。我使用控制台应用程序甚至我的 Windows 服务来查找正确的表:VacancyCategories。