【问题标题】:EF Core ignore property only to INSERTEF Core 忽略属性仅对 INSERT
【发布时间】:2020-10-07 00:51:44
【问题描述】:

我正在尝试设置我的实体以从表上不存在的 2 个属性中检索数据,基本上是通过执行 rawSql.当我在 entityBuilder 中映射这两个属性时,它运行良好,但是当我尝试从该实体插入新数据时,我收到与表中缺少的列相关的错误。当我将 Ignore 设置为这些属性时,它解决了缺少列错误,但停止检索数据。是否可以仅忽略插入/更新方向的列/属性?在这种情况下,属性 PlatformDescription 和 DriverDescription。

谢谢大家!

        public OrderMap(EntityTypeBuilder<Order> entityBuilder)
        {
            entityBuilder.HasKey(o => o.Id);
            entityBuilder.Property(o => o.CreationDate).IsRequired();
            entityBuilder.Property(o => o.ModifiedDate);
            entityBuilder.Property(o => o.CreatedBy).IsRequired();
            entityBuilder.Property(o => o.ModifiedBy);
            entityBuilder.Property(o => o.AutomobilePlate);
            entityBuilder.Property(o => o.DriverDriversLicense);
            entityBuilder.Property(o => o.LoginChecking);
            entityBuilder.Property(o => o.LoginPacking);
            entityBuilder.Property(o => o.LoginPicking);
            entityBuilder.Property(o => o.LoginDispatching);
            entityBuilder.Property(o => o.Platform);
            entityBuilder.Property(o => o.TrackingCode).IsRequired();
            entityBuilder.Property(o => o.PlatformDescription);
            entityBuilder.Property(o => o.DriverDescription);
            entityBuilder.Ignore("PlatformDescription");
            entityBuilder.Ignore("DriverDescription");
        }
var query = "SELECT A.Id ";
                query += ",A.AutomobilePlate ";
                query += ",A.CreatedBy ";
                query += ",A.CreationDate ";
                query += ",A.DriverDriversLicense ";
                query += ",A.LoginChecking ";
                query += ",A.LoginDispatching ";
                query += ",A.LoginPacking ";
                query += ",A.LoginPicking ";
                query += ",A.ModifiedBy ";
                query += ",A.ModifiedDate ";
                query += ",A.Platform ";
                query += ",A.Status ";
                query += ",A.TrackingCode ";
                query += ",B.Description PlatformDescription ";
                query += ",B.Complement ";
                query += ",C.Description DriverDescription ";
                query += " FROM [Order] A ";
                query += " LEFT JOIN Setup B ";
                query += "   ON A.Platform = B.Id ";
                query += " LEFT JOIN Setup C ";
                query += "   ON A.DriverDriversLicense = C.Id ";
                query += "WHERE A.CreationDate > DATEADD(DAY, -30, GETDATE()) ";

                return entities.FromSqlRaw(query).ToList();

【问题讨论】:

  • 这听起来像是一个 XY 问题。为什么要尝试使用原始 sql?您是否想将此实体定义为没有表 (entityBuilder.ToView(null))?您似乎也误解了Ignore 的目的,它是为了拥有一个不受数据库列支持的对象属性。
  • ... retrieve data from 2 properties that doesn't exist on the table - 你怎么能从表上不存在的东西中检索数据!我在这里错过了什么?
  • @atiyar 左加入

标签: c# .net entity-framework asp.net-core entity-framework-core


【解决方案1】:

给定你的 sql 查询;

SELECT A.Id
,A.AutomobilePlate
,A.CreatedBy
,A.CreationDate
,A.DriverDriversLicense
,A.LoginChecking
,A.LoginDispatching
,A.LoginPacking
,A.LoginPicking
,A.ModifiedBy
,A.ModifiedDate
,A.Platform
,A.Status
,A.TrackingCode
,B.Description PlatformDescription
,B.Complement
,C.Description DriverDescription
 FROM [Order] A
 LEFT JOIN Setup B
   ON A.Platform = B.Id
 LEFT JOIN Setup C
   ON A.DriverDriversLicense = C.Id
WHERE A.CreationDate > DATEADD(DAY, -30, GETDATE())

看起来您真的只想定义 2 个实体及其关联的导航属性。这样你根本不需要使用原始 sql;

public class Order {
    public int Id { get; set; }
    public int? Platform { get; set; }
    public int? DriverDriversLicense { get; set; }
    // snip
    public virtual Setup SetupPlatform { get; set; }
    public virtual Setup SetupDriver { get; set; }
}

public class Setup {
    public int Id { get; set; }
    public string Description  { get; set; }
    // snip
}

public OrderMap(EntityTypeBuilder<Order> entityBuilder)
{
// snip
entityBuilder
    .HasOne(e => e.SetupPlatform)
    .WithOne()
    .HasForeignKey<Order>(e => e.Platform);
entityBuilder
    .HasOne(e => e.SetupDriver)
    .WithOne()
    .HasForeignKey<Order>(e => e.DriverDriversLicense);
}

可以在每次加载 Order 时强制加载每个 Setup 导航属性;

.HasForeignKey ... 
.Metadata.PrincipalToDependent.SetIsEagerLoaded(true);

并定义额外的属性,为方便起见,未映射到数据库中的 Order 表;

public class Order {
    [NotMapped]
    public string PlatformDescription => Platform?.Description;
    [NotMapped]
    public string DriverDescription => SetupDriver?.Description;
...

【讨论】:

  • 嗨@Jeremy Lakeman!听起来很有希望,但是当添加 EagerLoaded 时,我收到一个错误:System.NullReferenceException: 'Object reference not set to an instance of an object。带有空堆栈跟踪
  • 你明白了,伙计,谢谢!但关于急切加载,我必须使用 Include 才能使其工作。
【解决方案2】:

只需将 [NotMapped] 用于此表中不存在的 2 个新属性。例如,订单模型类,

public class Order
{
    [NotMapped]
    public string NewProperty1 { get; set; }
    [NotMapped]
    public string NewProperty2 { get; set; }
}

已编辑

您可以使用此 linq 并将这些表和列更改为您自己的表和列。

var setup = db.TSetup;
var list = (from a in db.TOrder
            from platform in setup.Where(x => x.Id == a.Platform).DefaultIfEmpty()
            from driver in setup.Where(x => x.Id == a.DriverDriversLicense).DefaultIfEmpty()
            select new TOrder()
            {
                Id = a.Id,
                Name = a.Name,
                PlatformDescription = platform.Description,
                DriverDescription = driver.Description
            }).ToList();

【讨论】:

  • 这不行。他的属性对应于他想要读取的列。
  • 你以前用过[NotMapped]吗?仍然可以从中读取。 [NotMapped] with column 可以在选择时读取并在插入/更新时被忽略。
  • 我用过。这意味着属性被排除在 EF 模型之外。它们没有映射到数据库列
  • NotMapped 不起作用:“Microsoft.EntityFrameworkCore.DbUpdateException: '更新条目时出错。有关详细信息,请参阅内部异常。'”
  • @Tbocc,你需要删除 entityBuilder.Property(o => o.PlatformDescription); entityBuilder.Property(o => o.DriverDescription); entityBuilder.Ignore("PlatformDescription"); entityBuilder.Ignore("DriverDescription");
猜你喜欢
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 2021-08-05
  • 2023-04-02
  • 1970-01-01
  • 2018-11-10
  • 1970-01-01
  • 2021-12-26
相关资源
最近更新 更多