I get UpdateException when i try to Update a collection property - entity-framework

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.

Related

LINQ query throw exception on FirstOrDefault method

I'm using EF core, and I have a many-to-many relationship between two entity
IotaProject <--> User
Here's entities & dto related to the question
public class IotaProject
{
[Key]
public int Id { get; set; }
[Required]
public string ProjectName { get; set; }
[Required]
public DateTime Create { get; set; }
public ICollection<ProjectOwnerJoint> Owners { get; set; } = new List<ProjectOwnerJoint>();
}
public class ProjectOwnerJoint
{
public int IotaProjectId { get; set; }
public IotaProject IotaProject { get; set; }
public int UserId { get; set; }
public User User { get; set; }
}
public class User
{
[Key]
public int Id { get; set; }
[Required]
public string FullName { get; set; }
[Required]
public string ShortName { get; set; }
[Required]
public string Email { get; set; }
public ICollection<ProjectOwnerJoint> OwnedProjects { get; set; } = new List<ProjectOwnerJoint>();
}
public class ApplicationDbContext : DbContext
{
public DbSet<IotaProject> IotaProjects { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<ProjectOwnerJoint> ProjectOwnerJoint { get; set; }
}
public class IotaProjectDisplayDto
{
public int Id { get; set; }
public string ProjectName { get; set; }
public DateTime Create { get; set; }
public UserMinDto Owner { get; set; }
public int Count { get; set; }
public IEnumerable<UserMinDto> Reviewers { get; set; }
}
public class UserMinDto
{
public int Id { get; set; }
public string FullName { get; set; }
public string ShortName { get; set; }
}
Following LINQ is the problem, the LINQ purpose is to convert IotaProject to IotaProjectDisplayDto, and key part is that Owners property of IotaProject is ICollection and Owner property in IotaProjectDisplayDto is just one single element UserMinDto, so I only need to get the first element of IotaProject's Owners and that's FirstOrDefault() comes.
IEnumerable<IotaProjectDisplayDto> results = _db.IotaProjects.Select(x => new IotaProjectDisplayDto
{
Id = x.Id,
ProjectName = x.ProjectName,
Create = x.Create,
Owner = x.Owners.Select(y => y.User).Select(z => new UserMinDto { Id = z.Id, FullName = z.FullName, ShortName = z.ShortName }).FirstOrDefault()
});
return results;
it throws run-time exception
Expression of type 'System.Collections.Generic.List`1[ToolHub.Shared.iota.UserMinDto]' cannot be used for parameter
of type 'System.Linq.IQueryable`1[ToolHub.Shared.iota.UserMinDto]'
of method 'ToolHub.Shared.iota.UserMinDto FirstOrDefault[UserMinDto](System.Linq.IQueryable`1[ToolHub.Shared.iota.UserMinDto])' (Parameter 'arg0')
I'm guessing it's probably related to deferred execution, but after read some posts, I still can't resolve it.
Any tips would be appreciated.
Right now, the only way I can get this work is I change type of Owner property in IotaProjectDisplayDto into IEnumrable, which will no longer need FirstOrDefault() to immediate execution. And later on, I manually get the first element in the client to display.
This issue happened in Microsoft.EntityFrameworkCore.SqlServer 3.0.0-preview7.19362.6
I end up downgrade to EF core stable 2.2.6 as Ivan suggested in comment, and everything works fine.

Microsoft Entity Framework Core Parent with 2 Children [duplicate]

This question already has answers here:
EF Core returns null relations until direct access
(2 answers)
Closed 4 years ago.
So I have 3 classes:
public class OwnerDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
public class SitterDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
public class ReviewDto
{
public int Id { get; set; }
public int Rating { get; set; }
//[ForeignKey("OwnerId")]
public OwnerDto Owner { get; set; }
//[ForeignKey("SitterId")]
public SitterDto Sitter { get; set; }
}
But I can't figure out how to do the proper modelBuilder. Everything I tried fails :( I am learning so bear with me.
My closest attempt was this:
modelBuilder.Entity<ReviewDto>()
.HasOne(t => t.Owner).WithMany().HasForeignKey("OwnerId");
Basically Owner and Sitter are always null :( Should i keep the [ForeignKey()] stuff or should i use a different extension method?
Declare all classes with navigation properties to each other. Mark one of the tables (the dependent table) with the ForeignKey attribute on its Primary Key.
EF infers one-to-many from this:
public class OwnerDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public ICollection<ReviewDto> Reviewers{ get; set; }
public ICollection<SitterDto> Sitters{ get; set; }
}
public class SitterDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public int OwnerId{ get; set; }
[ForeignKey("OwnerId")]
public OwnerDto Owner { get; set; }
}
public class ReviewDto
{
public int Id { get; set; }
public int Rating { get; set; }
public int OwnerId{ get; set; }
[ForeignKey("OwnerId")]
public OwnerDto Owner { get; set; }
}
and EF infers one-to-one from this:
public class OwnerDto
{
...
public ReviewDto Review{ get; set; }
...
}
public class ReviewDto
{
[ForeignKey("Owner")]
public int OwnerId { get; set; }
public OwnerDto Owner{ get; set; }
...
}
You need to refer Eager Loading in this scenario, You can use the Include method to specify related data to be includethe d in query results.
var query = from review in context.Review.Include(o => o.Owner).Include(s=>s.Sitter) select review;

Sequence contains more than one matching element on schema update

I´m using ef-core inheritance like this:
public abstract class Person
{
public int Id { get; set; }
public string Name { get; set; }
public PersonType PersonType { get; set; }
public int PersonTypeId { get; set; }
public double Height { get; set; }
[Timestamp]
public byte[] Timestamp { get; set; }
}
public class Daughter : Person
{
public double Weigth { get; set; }
public DateTime SomeDate { get; set; }
}
public abstract class Son : Person
{
public DateTime BirthDate { get; set; }
public DateTime GraduationDate { get; set; }
}
public class SingleSon : Son
{
}
public class SonWithDaughter : Son
{
public int Daughter { get; set; }
public Daughter Daughter { get; set; }
}
In DbContext:
public DbSet<PersonType> PersonTypes { get; set; }
public DbSet<Daughter> Daughters { get; set; }
public DbSet<SingleSon> SingleSons { get; set; }
public DbSet<SonWithDaughter> SonWithDaughters { get; set; }
When I update sql server database (dotnet ef database update) it throws a
System.InvalidOperationException, Sequence contains more than one
matching element
Any ideas about how to solve this?
UPDATE
ef migrations console output
This is issue #5894. It will be fixed in version 1.0.1. Until that's released, you can use the nightly feed.

Returning Entity with its children

Hi I am trying to return all vehicles with their recorded mileage through an api using ASP.Net Core with the following code:
// GET: api/values
[HttpGet]
public IEnumerable<Vehicle> Get()
{
return _context.Vehicles.Include(m=>m.Mileages).ToList();
}
However this only returns the first vehicle with its mileages and not the others (there are five dummy vehicles in the db all with an initial mileage).
If I change the code to:
// GET: api/values
[HttpGet]
public IEnumerable<Vehicle> Get()
{
return _context.Vehicles.ToList();
}
it returns the full list of vehicles but no mileage.
My class files are:
public class Vehicle
{
public Vehicle()
{
Mileages = new List<Mileage>();
}
public int Id { get; set; }
public string Registration { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Marked Marked { get; set; }
public ICollection<Mileage> Mileages { get; set; }
}
and
public class Mileage
{
public int Id { get; set; }
public DateTime MileageDate { get; set; }
public string RecordedMileage { get; set; }
//Navigation Properties
public int VehicleId { get; set; }
public Vehicle Vehicle { get; set; }
}
thanks for looking!
Tuppers
you can have them auto-load (lazy loading) using proxies... but for that, your foreign entities and collections must be marked virtual in your POCOs:
public class Mileage
{
public int Id { get; set; }
public DateTime MileageDate { get; set; }
public string RecordedMileage { get; set; }
//Navigation Properties
public int VehicleId { get; set; }
public virtual Vehicle Vehicle { get; set; }
}
public class Vehicle
{
public Vehicle()
{
Mileages = new List<Mileage>();
}
public int Id { get; set; }
public string Registration { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Marked Marked { get; set; }
public virtual ICollection<Mileage> Mileages { get; set; }
}
The proxy creation and lazy loading turned on, but that's the default in EF6.
https://msdn.microsoft.com/en-us/data/jj574232.aspx
Let me know if this works.
Well after a lot of searching I managed to find a solution. I used the following:
[HttpGet]
public IEnumerable<VehicleDto> Get()
{
var query = _context.Vehicles.Select(v => new VehicleDto
{
Registration = v.Registration,
Make = v.Make,
Model = v.Model,
Marked = v.Marked,
Mileages = v.Mileages.Select(m => new MileageDto
{
MileageDate = m.MileageDate,
RecordedMileage = m.RecordedMileage
})
.ToList(),
})
.ToList();
return (IEnumerable<VehicleDto>) query.AsEnumerable();
this doesn't seem to be the most elegant way of doing this, if anyone could offer any advice but it does return what is required.
The DTO's look like:
public class VehicleDto
{
public string Registration { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Marked Marked { get; set; }
public ICollection<MileageDto> Mileages { get; set; }
}
and
public class MileageDto
{
public DateTime MileageDate { get; set; }
public string RecordedMileage { get; set; }
}
Thanks for taking the time to look at this
Tuppers

Get multiple tables data through Entity Framework with Generic Repository and Unit Of work

I am working on Web-API project and using Entity Framework with Generic Repository and Unit Of work. Basically i follow a tutorial for this.
Here is my table architecture.
Entity
public class ProductEntity
{
public int ProductId { get; set; }
public string ProductCode { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public string ProductImgName { get; set; }
public bool IsActive { get; set; }
public int PrimaryCatId { get; set; }
public int SecondaryCatId { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public System.DateTime CreateDate { get; set; }
public List<PrimaryProductEntity> objPrimaryProduct { get; set; }
public List<SecondaryProductEntity> objSecondaryProduct { get; set; }
}
public class PrimaryProductEntity
{
public int PrimaryCatId { get; set; }
public string PrimaryCatName { get; set; }
}
public class SecondaryProductEntity
{
public int SecondaryCatId { get; set; }
public string SecondaryCatName { get; set; }
public int PrimaryCatId { get; set; }
}
Services Code
public IEnumerable<BusinessEntities.ProductEntity> GetAllProducts()
{
var products = _unitOfWork.ProductRepository.GetAll().ToList();
var primaryProducts = _unitOfWork.PrimaryProductRepository.GetAll().ToList();
var secondaryProducts = _unitOfWork.SecondaryProductRepository.GetAll().ToList();
if (products.Any())
{
Mapper.CreateMap<tblProduct, ProductEntity>();
var proInfo = from P in products
join PP in primaryProducts on P.PrimaryCatId equals PP.PrimaryCatId
join SP in primaryProducts on P.SecondaryCatId equals SP.SecondaryCatId
select P;
var productsModel = Mapper.Map<List<tblProduct>, List<ProductEntity>>(proInfo);//getting error
return productsModel;
}
return null;
}
i know my implementation is wrong, i don't know what to write in code for fetch data from multiple tables. Please help me.
Required Data
ProductID,ProductName, PrimaryCatName, SecondaryCatName,Price, Quantity
Your Product Entity class Doesn't require a List<PrimaryProductEntity> and List<SecondaryProductEntity>. I suppose according to your class diagram Each Product is associated with one PrimaryProductEntity and one SecondaryProductEntity.
Once your model class is corrected, you would be able to access the properties of the navigation. I am not so good with writing a Query the way you want. But i hope you could get an idea of what you should be doing