我有以下型号:
public partial class Vehicule
{
public long VehiculeId { get; set; }
public int CompanyId { get; set; }
public string PhoneNumber { get; set; }
public long? HardwareId { get; set; }
public int? VehiculeUserId { get; set; }
public int GpsBoxType { get; set; }
public string Category { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int IconId { get; set; }
public int GpsBoxTrackingDelay { get; set; }
public string Address { get; set; }
public int? AddressProtocol { get; set; }
public string BoardId { get; set; }
public ulong RowVersion { get; set; }
public bool RowEnabled { get; set; }
public DateTime? DbInsertTime { get; set; }
public string CustomId { get; set; }
public bool? HasGeoWorker { get; set; }
public virtual Company Company { get; set; }
public virtual Device Device { get; set; }
public virtual ICollection<FleetDetail> FleetDetails { get; set; }
public Vehicule()
{
FleetDetails = new HashSet<FleetDetail>();
}
}
和
public partial class Device
{
public long Imei { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string Name { get; set; }
public string OsVersion { get; set; }
public string AppVersion { get; set; }
public ulong RowVersion { get; set; }
public virtual DeviceRegistrationFree DeviceRegistrationFree { get; set; }
public virtual DeviceRegistrationPackage DeviceRegistrationPackage { get; set; }
public virtual DeviceRegistrationStore DeviceRegistrationStore { get; set; }
public virtual Registration Registration { get; set; }
public virtual Vehicule Vehicule { get; set; }
}
配置如下:
builder.Entity<Vehicule>(entity =>
{
entity.ToTable("Vehicule");
entity.HasIndex(e => e.HardwareId)
.HasName("UIX_HardwareID")
.IsUnique();
entity.HasIndex(e => e.RowVersion)
.HasName("IX_RowVersion");
entity.HasIndex(e => e.VehiculeUserId)
.HasName("UIX_VehiculeUserID")
.IsUnique();
entity.HasIndex(e => new { e.BoardId, e.CompanyId })
.HasName("UIX_CompanyIdVehiculeBoardId")
.IsUnique();
entity.HasIndex(e => new { e.GpsBoxType, e.RowEnabled })
.HasName("IX_RowEnabled");
entity.HasIndex(e => new { e.VehiculeId, e.Name, e.CompanyId, e.RowEnabled })
.HasName("IX_CompanyID_RowEnabled");
entity.Property(e => e.VehiculeId).HasColumnName("VehiculeID");
entity.Property(e => e.Address).HasMaxLength(250);
entity.Property(e => e.BoardId)
.HasColumnName("BoardID")
.HasMaxLength(50)
.IsUnicode(false);
entity.Property(e => e.Category).HasMaxLength(128);
entity.Property(e => e.CompanyId).HasColumnName("CompanyID");
entity.Property(e => e.CustomId).HasMaxLength(128);
entity.Property(e => e.DbInsertTime).HasColumnType("datetime");
entity.Property(e => e.Description).HasMaxLength(1024);
entity.Property(e => e.HardwareId).HasColumnName("HardwareID");
entity.Property(e => e.IconId).HasColumnName("IconID");
entity.Property(e => e.Name).HasMaxLength(128);
entity.Property(e => e.PhoneNumber)
.HasMaxLength(30)
.IsUnicode(false);
// https://github.com/aspnet/EntityFrameworkCore/issues/5936#issuecomment-397987482
entity.Property(e => e.RowVersion)
.HasConversion(new NumberToBytesConverter<ulong>())
.IsRowVersion();
entity.Property(e => e.VehiculeUserId).HasColumnName("VehiculeUserID");
entity.HasOne(d => d.Company)
.WithMany(p => p.Vehicule)
.HasForeignKey(d => d.CompanyId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_GpsBox_Company");
// Model the relationship between Vehicule and Device
// We don't need a Foreign key in the database though
entity.HasOne(d => d.Device)
.WithOne(v => v.Vehicule)
.HasForeignKey<Device>(d => d.Imei)
// The key column for the JOIN is not the primary key but a custom column
// HardwareId in Vehicule => Imei in Device
.HasPrincipalKey<Vehicule>(v => v.HardwareId);
entity.HasMany(d => d.FleetDetails)
.WithOne(f => f.Vehicule)
.HasForeignKey(d => d.VehiculeId);
});
和
builder.Entity<Device>(entity =>
{
entity.HasKey(e => e.Imei);
entity.ToTable("Device", SqlSchema.SafeProtect);
entity.Property(e => e.Imei).ValueGeneratedNever();
entity.Property(e => e.AppVersion)
.HasMaxLength(30)
.IsUnicode(false);
entity.Property(e => e.Brand).HasMaxLength(255);
entity.Property(e => e.Model).HasMaxLength(255);
entity.Property(e => e.Name).HasMaxLength(255);
entity.Property(e => e.OsVersion)
.HasMaxLength(30)
.IsUnicode(false);
entity.Property(e => e.RowVersion)
.HasConversion(new NumberToBytesConverter<ulong>())
.IsRowVersion();
entity.HasOne(v => v.Vehicule)
.WithOne(d => d.Device)
.HasForeignKey<Vehicule>(v => v.HardwareId);
});
两个实体之间存在一对一的关系。
以下linq查询:
IQueryable<Vehicule> query =
(from Vehicule entity in delayedDisposer.Item.VehicleDbSet
where entity.HardwareId == hardwareID
select entity).Include(v => v.Device).Include(v => v.FleetDetails).AsNoTracking();
var vehicule = query.First();
在无效查询中生成,失败并出现以下错误:
System.Data.SqlClient.SqlException:'无效的列名'Protocol1'。
这是由实体框架生成的sql:
exec sp_executesql N'SELECT TOP(1) [entity].[VehiculeID], [entity].[Address], [entity].[AddressProtocol], [entity].[BoardID], [entity].[Category], [entity].[CompanyID], [entity].[CustomId], [entity].[DbInsertTime], [entity].[Description], [entity].[GpsBoxTrackingDelay], [entity].[GpsBoxType], [entity].[HardwareID], [entity].[HasGeoWorker], [entity].[IconID], [entity].[Name], [entity].[PhoneNumber], [entity].[Protocol1], [entity].[RowEnabled], [entity].[RowVersion], [entity].[VehiculeUserID], [entity.Device].[Imei], [entity.Device].[AppVersion], [entity.Device].[Brand], [entity.Device].[Model], [entity.Device].[Name], [entity.Device].[OsVersion], [entity.Device].[RowVersion]
FROM [Vehicule] AS [entity]
LEFT JOIN [SafeProtect].[Device] AS [entity.Device] ON [entity].[HardwareID] = [entity.Device].[Imei]
WHERE [entity].[HardwareID] = @__hardwareID_0
ORDER BY [entity].[VehiculeID]',N'@__hardwareID_0 bigint',@__hardwareID_0=866857042994208
我完全不知道为什么使用此列名。我只能说的是,AddressProtocol列是Protocol实体的一对一外键,而后者又包含一个 Protocol1 属性:
public partial class Protocol
{
public Protocol()
{
Message = new HashSet<Message>();
Vehicule = new HashSet<Vehicule>();
VehiculeUser = new HashSet<VehiculeUser>();
}
public int Protocol1 { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Message> Message { get; set; }
public virtual ICollection<Vehicule> Vehicule { get; set; }
public virtual ICollection<VehiculeUser> VehiculeUser { get; set; }
}
和
builder.Entity<Protocol>(entity =>
{
entity.HasKey(e => e.Protocol1);
entity.ToTable("Protocol", "cst");
entity.Property(e => e.Protocol1)
.HasColumnName("Protocol")
.ValueGeneratedNever();
});
任何帮助表示赞赏。
编辑:我通过从“协议”实体中删除“车辆”集合来解决了这个问题。我可能会问另一个问题,以了解为什么Entity Framework在没有/未考虑配置的情况下遍历图形。我会在Github上打开一个有关列名的问题。