Reputation: 793
I have tried almost everything from StackOverflow to prevent these errors. I have no idea what am I doing wrong. When I'm starting with some changes to remove one bug, the second appear and vice versa. I don't know if it connects to DB, or can it initialize DB, or cannot. It looks like my DB file is empty - I'm using SQLite and I want to use Code First mechanism of EF.
My code
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; }
}
}
Calling DB
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();
}
And connection settings
<?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>
Upvotes: 1
Views: 381
Reputation: 793
This is not a struct! public PositionBase DevicePosition { get; set; }. Changing it according to rules from:
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; } // [°]
}
to
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; }
}
and adding it to DbContext solves the problem.
public DbSet<PositionBase> PositionBases { get; set; }
Second challenge is that EF doesn't support object types, so it also can cause problems!
Upvotes: 0
Reputation: 109185
You're defining a 1 (MessageDescription
) : 0..1 (UnifiedPositionMessage
) association here.
What EF wants to do is define a primary key in one table that at the same time is a foreign key to the other table. In your case, UnifiedPositionMessage
would have an non-autoincrementing Id field that points to MessageDescription.Id
, which is an auto-incrementing identity column. So any UnifiedPositionMessage
record can only exist if its MessageDescription
exists. This is enforced by the [Required]
attribute.
In this scenario it is no use to have explicit foreign key fields in your entities: there's only one FK that's also a PK, so you will never be able to set it.
So you can remove MessageDescriptionId
from your model and, second, tell EF how to map your entities:
modelBuilder.Entity<UnifiedPositionMessage>()
.HasRequired(u => u.MessageDescription)
.WithOptional(md => md.UnifiedPositionMessage);
(this is in the DbContext.OnModelCreating
override)
Upvotes: 1
Reputation: 494
That is probably because Id can't be 0!
var msgDesc = new MessageDescription() {IsMessageValid = true, Id = 0, UnifiedPositionMessage = e.Frame};
You can set your msgDesc as
var msgDesc = new MessageDescription {IsMessageValid = true, UnifiedPositionMessage = e.Frame};
So your records in the db all will have unique Id's.
Upvotes: 0