在尝试编写一些干净的模型类库时,我使用的是EF5 Code First。使用EntityTypeConfiguration将各种属性映射到托管在SQL Server 2005服务器实例上的2个VIEWS列中。EF5代码首先在DbSet查询中执行意外的JOIN
注意:我知道有一些不良的表列命名正在进行,但由于它是现有的数据库,因此我必须应对此问题。请原谅我。
做管道后,我可以查询客户账户...
var context = new Data.EntityContext();
public IQueryable<ClientAccount> GetClients(List<string> usernameOrEmail)
{
return context.ClientAccount.Where(p => usernameOrEmail.Contains(p.UserName) || usernameOrEmail.Contains(p.Email)).Include("Company").AsQueryable();
}
...匹配的客户端返回,其中包括公司的详细信息。
但是,当试图仅获取公司列表时,结果包含大量重复项。
var companies = data.Companies.Where(c => c.IsActive).OrderBy(c => c.Name);
使用SQL Server Profiler中我发现,对我的原因尚不清楚,发动机配备了一个LEFT OUTER JOIN,以包括客户端的用户id以及:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Company] AS [Company],
[Extent1].[Address] AS [Address],
[Extent1].[AddressSuffix] AS [AddressSuffix],
[Extent1].[Zip] AS [Zip],
[Extent1].[City] AS [City],
[Extent1].[State] AS [State],
[Extent1].[CountryName] AS [CountryName],
[Extent1].[Telephone] AS [Telephone],
[Extent1].[Fax] AS [Fax],
[Extent1].[Url] AS [Url],
[Extent1].[Latitude] AS [Latitude],
[Extent1].[Longitude] AS [Longitude],
[Extent1].[isPublic] AS [isPublic],
[Extent1].[active] AS [active],
[Extent1].[parent] AS [parent],
[Extent2].[userId] AS [userId]
FROM [dbo].[VIEW_CompaniesCountryContinent] AS [Extent1]
LEFT OUTER JOIN [dbo].[PassportAccounts] AS [Extent2] ON ([Extent2].[companyId] IS NOT NULL) AND ([Extent1].[Id] = [Extent2].[companyId])
WHERE 1 = [Extent1].[active]
我不知道为什么,因为我没有链接到公司模式的客户。 VIEW不包括用户表,只针对公司表。
很明显,我错过了某些东西,我希望你能让我回到正轨。 下面你会找到关于模型,上下文和实体规范的一些细节。 谢谢!
代码信息:
的模式是相当简单的...
public class ClientAccount : IUserAccount
{
public ClientAccount() { }
[Key]
public int ClientId { get; set; }
[DisplayName("User Name")]
public string UserName { get; set; }
[DisplayName("First Name")]
public string FirstName { get; set; }
[DisplayName("Last Name")]
public string LastName { get; set; }
[DisplayName("Job Title")]
public string JobTitle { get; set; }
[DisplayName("Company")]
public virtual Company Company { get; set; }
[DisplayName("Direct Phone")]
public string PhoneDirect { get; set; }
[DisplayName("Mobile phone")]
public string PhoneMobile { get; set; }
[DisplayName("Registration Date")]
public DateTime DateRegistered { get; set; }
[DisplayName("Last Login")]
public DateTime LastLogin { get; set; }
[EmailAddress]
[DisplayName("Email")]
public string Email { get;set; }
public bool IsApproved { get; set; }
public bool IsActive { get; set; }
public bool IsLockedOut { get { return !IsActive; } }
public bool IsOnline
{
get { return (LastLogin.AddMinutes(10) > DateTime.Now); }
}
public DateTime LastActivityAt { get; set; }
}
public class Company
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Address2 { get; set; }
public string Zip { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string Telephone { get; set; }
public string Fax { get; set; }
public string Url { get; set; }
public string TimeZone { get; set; }
public Coordinate Coordinate { get; set; }
public bool IsPublic { get; set; }
public bool IsActive { get; set; }
public int ParentCompanyId { get; set; }
}
public class Coordinate
{
public decimal? Latitude { get; set; }
public decimal? Longitude { get; set; }
}
到目前为止,没有什么特别的(?右)。 的的DbContext:
public class EntityContext : DbContext
{
public EntityContext() : base("Name=EntityContext")
{
Database.SetInitializer<EntityContext>(null);
}
public EntityContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<EntityContext>(null);
}
public DbSet<ClientAccount> ClientAccount { get; set; }
public DbSet<Company> Companies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new CompanyConfiguration());
modelBuilder.Configurations.Add(new ClientAccountConfiguration());
base.OnModelCreating(modelBuilder);
}
}
而且EntityTypeConfigurations ...
public class ClientAccountConfiguration : EntityTypeConfiguration<ClientAccount>
{
public ClientAccountConfiguration()
: base()
{
HasKey(p => p.ClientId);
ToTable("ClientAccounts"); // VIEW ClientAccounts
Property(p => p.ClientId)
.HasColumnName("userId")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.IsRequired();
Property(p => p.Email)
.HasColumnName("userEmail")
.IsRequired();
Property(p => p.UserName)
.HasColumnName("userLogin")
.IsRequired();
Property(p => p.FirstName).HasColumnName("userFirstName");
Property(p => p.LastName).HasColumnName("userLastName");
Property(p => p.PhoneDirect).HasColumnName("userPhoneDirect");
Property(p => p.PhoneMobile).HasColumnName("userPhoneMobile");
Property(p => p.JobTitle)
.HasColumnName("userPosition");
HasOptional(p => p.Company)
.WithOptionalDependent()
.Map(p => p.MapKey("companyId"));
Property(p => p.IsApproved).HasColumnName("Employed");
Property(p => p.IsActive).HasColumnName("active");
Property(p => p.LastActivityAt).HasColumnName("updated");
Property(p => p.LastLogin).HasColumnName("LastLogin").IsOptional();
Property(p => p.DateRegistered).HasColumnName("created");
}
}
public class CompanyConfiguration : EntityTypeConfiguration<Company>
{
public CompanyConfiguration()
{
this.HasKey(c => c.ID);
this.ToTable("VIEW_CompaniesCountryContinent");
this.Property(c => c.ID)
.HasColumnName("Id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(c => c.Name)
.HasColumnName("Company")
.IsRequired();
this.Property(c => c.Address).HasColumnName("Address");
this.Property(c => c.Address2).HasColumnName("AddressSuffix");
this.Property(c => c.Country).HasColumnName("CountryName");
this.Property(c => c.City).HasColumnName("City");
this.Property(c => c.Zip).HasColumnName("Zip");
this.Property(c => c.State).HasColumnName("State");
this.Property(c => c.Coordinate.Latitude).HasColumnName("Latitude");
this.Property(c => c.Coordinate.Longitude).HasColumnName("Longitude");
this.Property(c => c.TimeZone).HasColumnName("timezone");
this.Property(c => c.IsPublic).HasColumnName("isPublic");
this.Property(c => c.IsActive).HasColumnName("active");
this.Property(c => c.ParentCompanyId).HasColumnName("parent");
}
}
什么是'data'在'data.Companies.Where'?只是上下文? –
顺便说一句,在你给的sql中,你有'[Extent2]。[userId] AS [userId]'。它应该从哪里来? “var companies”是可查询的吗?如果是,那么在哪里以及如何使用? –
@Raphael:是的,数据是上下文 sql是通过使用Sql Profiler获得的,并且由EntityFramework(而不是我)生成。 userId是困惑我,不知何故EF执行此JOIN,但我不明白为什么。这绝不是公司模式的一部分。 –