无法确定 OR 的主端 “值不能为空,参数名称'键'”
本文关键字:参数 值不能为空 OR 不能 无法确定 | 更新日期: 2023-09-27 18:35:39
我已经尝试了StackOverflow中的几乎所有内容来防止这些错误。我不知道我做错了什么。当我开始进行一些更改以删除一个错误时,会出现第二个错误,反之亦然。我不知道它是否连接到DB,或者它可以初始化DB,或者不能。看起来我的数据库文件是空的 - 我正在使用 SQLite,我想使用 EF 的代码优先机制。
我的代码
using System.Data.Entity;
using ControlCenter;
namespace ControlCenter
{
public class IncomingMessaggesContext: DbContext
{
public DbSet<UnifiedPositionMessage> UnifiedPositionMessages { get; set; }
public DbSet<MessageDescription> MessageDescriptions { get; set; }
static IncomingMessaggesContext()
{
Database.SetInitializer<IncomingMessaggesContext>(null);
}
}
}
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ControlCenter.CommunicationGateway
{
using System;
using TrackingDevices.Positioning;
public class UnifiedPositionMessage
{
public int Id { get; set; }
public uint DeviceID { get; set; }
public DateTime ReceiveTime { get; set; }
public PositionBase DevicePosition { get; set; }
public object UserPayload { get; set; }
public int MessageDescriptionId { get; set; }
[ForeignKey("Id")]
[Required]
public virtual MessageDescription MessageDescription { get; set; }
}
public class MessageDescription
{
public int Id { get; set; }
public bool IsMessageValid { get; set; }
public virtual UnifiedPositionMessage UnifiedPositionMessage { get; set; }
}
}
调用数据库
using (var db = new IncomingMessaggesContext() )
{
var msgDesc = new MessageDescription() {IsMessageValid = true, Id = 0, UnifiedPositionMessage = e.Frame};
db.MessageDescriptions.Add(msgDesc);
db.UnifiedPositionMessages.Add(e.Frame);
db.SaveChanges();
}
和连接设置
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<connectionStrings>
<add name="IncomingMessaggesContext"
connectionString="Data Source=c:'temp'Messages.db;"
providerName="System.Data.SQLite" />
</connectionStrings>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="SQLite Data Provider"
invariant="System.Data.SQLite"
description="Data Provider for SQLite"
type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data>
</configuration>
您在这里定义了一个 1 ( MessageDescription
) : 0..1 (UnifiedPositionMessage
) 关联。
EF 要做的是在一个表中定义一个主键,该主键同时是另一个表的外键。在您的情况下,UnifiedPositionMessage
将有一个指向 MessageDescription.Id
的非自动递增 Id 字段,这是一个自动递增的标识列。因此,任何UnifiedPositionMessage
记录只有在其MessageDescription
存在时才能存在。这是由 [Required]
属性强制执行的。
在这种情况下,实体中显式外键字段是没有用的:只有一个 FK 也是 PK,因此您将永远无法设置它。
因此,可以从模型中删除MessageDescriptionId
,然后告诉 EF 如何映射实体:
modelBuilder.Entity<UnifiedPositionMessage>()
.HasRequired(u => u.MessageDescription)
.WithOptional(md => md.UnifiedPositionMessage);
(这是在DbContext.OnModelCreating
覆盖中)
这可能是因为 Id 不能为 0!
var msgDesc = new MessageDescription() {IsMessageValid = true, Id = 0, UnifiedPositionMessage = e.Frame};
您可以将 msgDesc 设置为
var msgDesc = new MessageDescription {IsMessageValid = true, UnifiedPositionMessage = e.Frame};
因此,您在数据库中的记录都将具有唯一的 Id。
这不是结构体!public PositionBase DevicePosition { get; set; }.根据以下规则更改它:
public class PositionBase
{
public DateTime GPSTime { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public float Speed { get; set; } // [km/h]
public float Course { get; set; } // [°]
}
自
public class PositionBase
{
public int Id { get; set; }
public DateTime GPSTime { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public float Speed { get; set; } // [km/h]
public float Course { get; set; } // [°]
[ForeignKey("Id")]
[Required]
public virtual UnifiedPositionMessage UnifiedPositionMessage { get; set; }
}
并将其添加到 DbContext 可以解决问题。
public DbSet<PositionBase> PositionBases { get; set; }
第二个挑战是 EF 不支持对象类型,因此也可能导致问题!