Entity cannot load data from related class - entity-framework

i have 3 class like that and i used code first entity on .net
public class PersonModel
{
[Key]
public int PersonID { get; set; }
public string FullName { get ; set ; }
public string Phone { get ; set ; }
public string Adress { get; set ; }
public int NationalNumber { get ; set ; }
public List<SpecialtyToPersonModel> SpecialtyToPerson { get ; set ; }
}
public class SpecialtyModel
{
[Key]
public int SpecialtyID { get; set; }
public string SpecialtyName { get; set; }
public List<SpecialtyToPersonModel> SpecialtyToPerson { get; set; }
}
public class SpecialtyToPersonModel{
[Key]
public int SpecialtyToPersonID { get ; set ; }
public SpecialtyModel Specialty { get; set; }
public PersonModel Person { get;set; }
}
when i need to use specialityToPersonModel like this
var db = new EntityContext();
var aaa = db.SpecialtyToPersons;
return aaa.ToList(); // so Simple !
or like this :
var db = new EntityContext();
var aaa = db.SpecialtyToPersons
.Include(x=>x.Specialty)
.Include(x=>x.Person);
return aaa.ToList();
, it throw me out with this error :
Error Picture
An exception of type 'Npgsql.PostgresException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code: 'External component has thrown an exception.'

its my fault that make DB bad at first , its from db not code ...
i correct my code and run
dotnet ef migrations add InitialCreate
and
dotnet ef database update
again and so on ... Ty Anyway ...

So shouldn't SpecialtyToPersonModel look more like this
Public Class SpecialtyToPersonModel{
[Key]
Public int SpecialtyID { Get; Set; }
Public SpecialtyModel Specialty { Get; Set; }
Public int PersonID { Get; Set; }
Public PersonModel Person { Get;Set; }
}

Related

Parent object is null when getting child objects using Entity Framework

public class AcsBatchingDbContext : DbContext
{
public DbSet<CardHolder> CardHolders { get; set; }
public DbSet<AccessCard> AccessCards { get; set; }
}
public class CardHolder
{
public int CardHolderId { get; set; }
public ICollection<AccessCard> AccessCards { get; set; };
}
public class AccessCard
{
public int AccessCardId { get; set; }
public CardHolder CardHolder { get; set; }
}
When I try to get AccessCards
using (var db = new AcsBatchingDbContext())
{
var cards = db.AccessCards.ToList();
}
Where card.CardHolder = null
Why? Why EF doesnt grab the CardHolder?
Another question:
Why this expression doesnt compile?
db.AccessCards.Include(x => x.CardHolder).ToList();
Why the only options is to use is
db.AccessCards.Include("CardHolder").ToList();
You should use include to load CardHolder entity.
(This requires using System.Data.Entity;)
db.AccessCards.Include(x => x.CardHolder).ToList();
Alternatively, you can apply Include like this;
db.AccessCards.Include("CardHolder").ToList();

LiteDB null reference on insert

I ran into this problem where in I get a null reference exception on insert.
I have two object Models UserInfo and UserConfig. On the first trial, UserConfig references a UserInfo instance
public class UserConfigObject : IUserConfig
{
BsonRef("userInfo")]
public IUserInfo UserInfo { get; set; }
public string AssignedJob { get; set; }
public string[] QueueItems { get; set; }
}
public class UserInfoObject : IUserInfo
{
[BsonId]
public int ID { get; set; }
public string Name { get; set; }
public string Username { get; set; }
public string IPAddress { get; set; }
}
And a method to insert the data into the database
public void AddUser(IUserConfig user)
{
var uconCollection = DatabaseInstance.GetCollection<IUserConfig>("userConfig");
var uinCollection = DatabaseInstance.GetCollection<IUserInfo>("userInfo");
uinCollection.Insert(user.UserInfo);
uconCollection.Insert(user);
}
This set up works fine but when I try to change the reference to UserInfo references UserConfig
public class UserInfoObject : IUserInfo
{
[BsonId]
public int ID { get; set; }
public string Name { get; set; }
public string Username { get; set; }
public string IPAddress { get; set; }
[BsonRef("userConfig")]
public IUserConfig UserConfig { get; set; }
}
public class UserConfigObject : IUserConfig
{
[BsonRef("userInfo")]
public IUserInfo UserInfo { get; set; }
[BsonId(true)]
public int ConfigID { get; set; }
public string AssignedJob { get; set; }
public string[] QueueItems { get; set; }
}
With a method call for
public void AddUser(IUserInfo user)
{
var uconCollection = DatabaseInstance.GetCollection<IUserConfig>("userConfig");
var uinCollection = DatabaseInstance.GetCollection<IUserInfo>("userInfo");
uconCollection.Insert(user.UserConfig);
uinCollection.Insert(user);
}
It no longer works, it throws an System.NullReferenceException: 'Object reference not set to an instance of an object.' on uinCollection.Insert(user);
Either v3 or v4, it doesn't work with the latter set up
Had the same problem but with collections. I've tried to save collection of invitations like so:
using var db = new LiteRepository(_connectionString);
var invitations = new List<Invitation>
{
// populate list
};
db.Insert(invitations);
The problem is that T parameter resolved as IEnumerable<Invitation> not just Invitation, so if you are inserting a collection, set type explicitly.
db.Insert<Invitation>(invitations);

How to map a table to an enumerable property using entity framework? (Database first)

Suppose I had these two classes:
public class MyClass {
public int Id { get; set; }
public IEnumerable<MyData> MyDataCollection { get; set; }
}
public class MyData {
public int DataId { get; set; }
public string Data { get; set; }
public int Id { get; set; }
}
and I had two tables in my database:
MyClasses:
Id
1
2
MyDatas:
DataId Id Data
1 - 1 - "Hello"
2 - 1 - "World"
3 - 2 - "Hello World"
How do I use entity framework to link them up, so that I can do:
using (var db = new DataContext()) {
var data = db.MyClass.Where(c => c.ID == 1).MyDataCollection;
foreach (var item in data) Console.WriteLine(item.Data);
}
I have the other data but so far I've just written [NotMapped] above the MyDataCollection property, but obviously I want to get rid of that and have it mapped. How do I (correctly) map it?
You can do it by expanding your class with appropriate navigation properties to establish the joins between them by following EF standards
public class MyClass {
public MyClass()
{
MyDataCollection = new List<MyData>();
}
public int Id { get; set; }
public virtual ICollection<MyData> MyDataCollection { get; set; }
}
public class MyData {
public int DataId { get; set; }
public string Data { get; set; }
public int Id { get; set; }
public virtual MyClass MyClass { get; set; }
}
Make sure these 2 entities are declared in the dbcontext as below
public class MyContext: DbContext
{
public MyContext(): base()
{
}
public DbSet<MyClass> MyClasses { get; set; }
public DbSet<MyData> MyDatas { get; set; }
}

Entity framework replaces delete+insert with an update. How to turn it off

I want to remove a row in database and insert it again with the same Id, It sounds ridiculous, but here is the scenario:
The domain classes are as follows:
public class SomeClass
{
public int SomeClassId { get; set; }
public string Name { get; set; }
public virtual Behavior Behavior { get; set; }
}
public abstract class Behavior
{
public int BehaviorId { get; set; }
}
public class BehaviorA : Behavior
{
public string BehaviorASpecific { get; set; }
}
public class BehaviorB : Behavior
{
public string BehaviorBSpecific { get; set; }
}
The entity context is
public class TestContext : DbContext
{
public DbSet<SomeClass> SomeClasses { get; set; }
public DbSet<Behavior> Behaviors { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<SomeClass>()
.HasOptional(s => s.Behavior)
.WithRequired()
.WillCascadeOnDelete(true);
}
}
Now this code can be executed to demonstrate the point
(described with comments in the code below)
using(TestContext db = new TestContext())
{
var someClass = new SomeClass() { Name = "A" };
someClass.Behavior = new BehaviorA() { BehaviorASpecific = "Behavior A" };
db.SomeClasses.Add(someClass);
// Here I have two classes with the state of added which make sense
var modifiedEntities = db.ChangeTracker.Entries()
.Where(entity => entity.State != System.Data.Entity.EntityState.Unchanged).ToList();
// They save with no problem
db.SaveChanges();
// Now I want to change the behavior and it causes entity to try to remove the behavior and add it again
someClass.Behavior = new BehaviorB() { BehaviorBSpecific = "Behavior B" };
// Here it can be seen that we have a behavior A with the state of deleted and
// behavior B with the state of added
modifiedEntities = db.ChangeTracker.Entries()
.Where(entity => entity.State != System.Data.Entity.EntityState.Unchanged).ToList();
// But in reality when entity sends the query to the database it replaces the
// remove and insert with an update query (this can be seen in the SQL Profiler)
// which causes the discrimenator to remain the same where it should change.
db.SaveChanges();
}
How to change this entity behavior so that delete and insert happens instead of the update?
A possible solution is to make the changes in 2 different steps: before someClass.Behavior = new BehaviorB() { BehaviorBSpecific = "Behavior B" }; insert
someClass.Behaviour = null;
db.SaveChanges();
The behaviour is related to the database model. BehaviourA and B in EF are related to the same EntityRecordInfo and has the same EntitySet (Behaviors).
You have the same behaviour also if you create 2 different DbSets on the context because the DB model remains the same.
EDIT
Another way to achieve a similar result of 1-1 relationship is using ComplexType. They works also with inheritance.
Here an example
public class TestContext : DbContext
{
public TestContext(DbConnection connection) : base(connection, true) { }
public DbSet<Friend> Friends { get; set; }
public DbSet<LessThanFriend> LessThanFriends { get; set; }
}
public class Friend
{
public Friend()
{Address = new FullAddress();}
public int Id { get; set; }
public string Name { get; set; }
public FullAddress Address { get; set; }
}
public class LessThanFriend
{
public LessThanFriend()
{Address = new CityAddress();}
public int Id { get; set; }
public string Name { get; set; }
public CityAddress Address { get; set; }
}
[ComplexType]
public class CityAddress
{
public string Cap { get; set; }
public string City { get; set; }
}
[ComplexType]
public class FullAddress : CityAddress
{
public string Street { get; set; }
}

I get UpdateException when i try to Update a collection property

I am in an MVC4 application and i am using EF CodeFirst.
When I try to run the following code:
public void Autorizare(int cerereId, Persoana persoana)
{
var cerere = _db.Cereri.Find(cerereId);
cerere.Autorizare.Add(persoana);
_db.SaveChanges();
}
I get an error like this:
Entities in 'CerereDbContext.Persoane' participate in the 'Actiune_Executanti' relationship. 0 related 'Actiune_Executanti_Source' were found. 1 'Actiune_Executanti_Source' is expected.
i have tried Entity(Actiune).State = EntityState.Modified, but no results.
I have a main POCO:
public class Cerere
{
public int Id { get; set; }
...
public virtual ICollection<Actiune> Actiuni { get; set; }
...
}
the Actiune class looks like this
public class Actiune
{
public int Id { get; set; }
public DateTime Data { get; set; }
public String Nume { get; set; }
public virtual ICollection<Persoana> Executanti { get; set; }
public String Stadiu { get; set; }
public String Obs { get; set; }
}
And Persoana:
public class Persoana
{
public int Id { get; set; }
public DateTime Data { get; set; }
public String Nume { get; set; }
}
From your model the Cerere does not have a property named Autorizare; however it does have one named Actiuni. Which is of type Actiune not Persoana which is what you are trying to add to it. Please post the rest of the Class Definition.