Entity Framework -- An item with the same key has already been added - entity-framework-5

I am having an intermittent error that I am not able to figure out. When my application is starting up the following line gives me the error stated in the title.
IList<DataAgentStatus> list = dbContext.DataAgentStatus.ToList();
The "DataAgentStatus" table only has 12 rows in it and the primary key is a string with unique names in it.
Any thoughts or ideas on where I should look? Most times if I hit "Continue" the application runs fine.
DataAgentStatus class (NotificationObject is a prism object that implements INotifyPropertyChanged)
public class DataAgentStatus : NotificationObject
{
[Key]
public string DataAgentName { get; set; }
public DateTime? LastAccessDate { get; set; }
public bool ErrorState { get; set; }
public string ErrorMessage { get; set; }
public int? Quantity { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? LastModifiedDate { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
}
Entry on the DbContext class
public DbSet<DataAgentStatus> DataAgentStatus { get; set; }
Call Stack from error.
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Objects.ObjectStateManager.AddEntityEntryToDictionary(EntityEntry entry, EntityState state)
at System.Data.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Coordinator1.ReadNextElement(Shaper shaper)
at System.Data.Common.Internal.Materialization.Shaper1.SimpleEnumerator.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at WPF.Data.Models.DataAgentStatus.List(DataBroker dbContext) in c:\Projects\WPF - Trunk\src\Components\Framework.WPF\Data\Models\DataAgentStatus.cs:line 88
at Framework.WPF.Data.Models.DataAgentStatus.ReloadObjects(DataBroker dbContext) in c:\Projects\WPF - Trunk\src\Components\Framework.WPF\Data\Models\DataAgentStatus.cs:line 101
at WPF.Data.Models.DataAgentStatus.LoadByType(DataBroker dbContext, String statusName, Boolean forceReload) in c:\Projects\WPF - Trunk\src\Components\Framework.WPF\Data\Models\DataAgentStatus.cs:line 73
at Framework.WPF.Data.Models.DataAgentStatus.LoadByType(DataBroker dbContext, String statusName) in c:\Projects\WPF - Trunk\src\Components\Framework.WPF\Data\Models\DataAgentStatus.cs:line 66
at Base.Data.Handlers.ReferenceDataHandler.GetUserWebLinks(ReceivingDatabroker dbContext) in c:\Projects\WPF - Trunk\src\Receiving\Receiving.Base\Data\Handlers\ReferenceDataHandler.cs:line 40
at Base.Data.Agents.UserWebLinkDataAgent.UserLinks(ReceivingDatabroker dbContext) in c:\Projects\WPF - Trunk\src\Receiving\Receiving.Base\Data\Agents\UserWebLinkDataAgent.cs:line 41
at Receiving.Base.Data.Handlers.LoginHandler.timmy_Elapsed(Object sender, ElapsedEventArgs e) in c:\Projects\WPF - Trunk\src\Receiving\Receiving.Base\Data\Handlers\LoginHandler.cs:line 144
at System.Timers.Timer.MyTimerCallback(Object state)

Related

Automapper projection results in empty collection for nested Dto

I have a .Net Core 2 webapi in which I am using automapper to map to Dtos. Everything works fine, except I am seeing an unexpected behaviour when I map an object to a Dto, and where the Dto also contains mappings for a collection. E.g
CreateMap<Order, OrderDto>();
CreateMap<Product, ProductDto>();
Where classes are like this
public partial class Order
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products{ get; set; }
public int ProductCount {return Products.Count;}
}
public partial class Product
{
public int Id { get; set; }
public int OrderId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
The following works as expected;
The class is mapped, and the ProjectCount is correct in the Dto
public partial class OrderDto
{
public int Id { get; set; }
public virtual ICollection<Product> Products{ get; set; }
public int ProductCount{ get; set; }
}
_context.Orders.Include<>(Products).ProjectTo<>(OrderDto)
But doing the following, the productcount is always zero.
E.g. if I do this;
public partial class OrderDto
{
public int Id { get; set; }
public virtual ICollection<ProductDto> Products{ get; set; }
public int ProductCount{ get; set; }
}
public partial class ProductDto
{
public int Id { get; set; }
public int OrderId { get; set; }
public string Name { get; set; }
}
_context.Orders.Include<>(Products).ProjectTo<>(OrderDto)
Why does this happen, and how can I ensure that it doesnt? This is a real world example where I need a property which references the collection - and I need it in both the base and the Dto. I can do the following which works fine, but it doesnt appear that this should be how it works...
public partial class OrderDto
{
public int Id { get; set; }
public virtual ICollection<ProductDto> Products{ get; set; }
public int ProductCount {return Products.Count;}
}
public partial class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
}
_context.Orders.Include<>(Products).ProjectTo<>(OrderDto)
I profiled the SQL and found that Automapper changes the way the query is formed. Without the nested projection, two queries are made;
[Queries are more complex than this and use joins, but you get the idea]
Select Id from orders
Select Id,Name from products where productid in [select id from orders ]
With the nested projection, are executed for each nested Dto
Select Id from orders
Select Id,Name from products where id=1
Select Id,Name from products where id=2

How to give a Table name in Entity Framework by code first approach in .Net Framework 4.0?

In .NET 4.0 framework the System.ComponentModel.DataAnnotations.Schema doesn't work or doesn't support I think.
I am using a code-first approach and my database already exists, and also not using ADO.net Entity Data Model.
I already used the [Table] attribute and DatabaseGenerated attribute, it's not working causing a compilation error to occur.
This is my code:
Entity class:
public class myclass
{
public myclass()
{
//
// TODO: Add constructor logic here
//
}
[Key]
public int RECORDID { get; set; }
public string AA { get; set; }
public string CAT { get; set; }
public string CS { get; set; }
public int? FS { get; set; }
public int? CA { get; set; }
public int? DR { get; set; }
public int? UM { get; set; }
public int? ID { get; set; }
public double LAT { get; set; }
public double LON { get; set; }
public int? NIC { get; set; }
}
DbContext class:
public class classContext : DbContext
{
public classContext() : base("name=DBConnection")
{
//Disable initializer
Database.SetInitializer<classContext>(null);
}
public DbSet<myclass> myclasses { get; set; }
}
Or I have to add this override method of model creating, is it helpful or not?
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<myclass>().ToTable("Datatbl");
}
Help me out. Thanks
You can Use Table attribute over your class:
[Table("Datatbl")]
public class myclass
{
}

ServiceStack AutoQuery - Anomaly When Using "?Fields="

We have noticed an anomaly when using "?Fields=" in version 4.0.55 (pre-release on MyGet).
We have an Employee table with three 1:1 relationships - EmployeeType, Department and Title:
public partial class Employee {
[PrimaryKey]
[AutoIncrement]
public int ID { get; set; }
[References(typeof(EmployeeType))]
public int EmployeeTypeID { get; set; }
[References(typeof(Department))]
public int DepartmentID { get; set; }
[References(typeof(Title))]
public int TitleID { get; set; }
.
.
.
}
public class EmployeeType {
[PrimaryKey]
public int ID { get; set; }
public string Name { get; set; }
}
public class Department {
[PrimaryKey]
public int ID { get; set; }
public string Name { get; set; }
[Reference]
public List<Title> Titles { get; set; }
}
public class Title {
[PrimaryKey]
public int ID { get; set; }
[References(typeof(Department))]
public int DepartmentID { get; set; }
public string Name { get; set; }
}
The latest update to 4.0.55 allows related DTOs to be requested using ?Fields= on the query string like this:
/employees?fields=id,firstname,lastname,departmentid,department
Note that the "proper" way to request a related DTO (department) is to also request the foreign key field (departmentid, in this case).
We wondered if there was a way to return all of the Employee table fields and only selected related DTOs, so in testing we found that this request works:
/employees?fields=department
We get back all the Employee table fields plus the related Department DTO - with one strange thing - the Employee's ID field is populated with the Employee's TitleID values.
Specifying the foreign key field in the request fixes that anomaly:
/employees?fields=id,departmentid,department
but we lose all of the other Employee fields.
Is there a way that to get all of the Employee fields and selected related DTOs?
Here is our AutoQuery DTO:
[Route("/employees", "GET")]
public class FindEmployeesRequest : QueryDb<Employee>,
IJoin<Employee, EmployeeType>,
IJoin<Employee, Department>,
IJoin<Employee, Title> {
public int? ID { get; set; }
public int[] IDs { get; set; }
public string UserID { get; set; }
public string[] UserIDs { get; set; }
public int? EmployeeTypeID { get; set; }
public int[] EmployeeTypeIDs { get; set; }
public int? DepartmentID { get; set; }
public int[] DepartmentIDs { get; set; }
public int? TitleID { get; set; }
public int[] TitleIDs { get; set; }
public string LastNameStartsWith { get; set; }
public DateTime[] DateOfBirthBetween { get; set; }
public DateTime[] HireDateBetween { get; set; }
public bool? IsActive { get; set; }
[QueryDbField(Template = "(MONTH({Field}) = {Value})", Field = "DateOfBirth")]
public int? BirthMonth { get; set; }
[QueryDbField(Template = "(DAY({Field}) = {Value})", Field = "DateOfBirth")]
public int? BirthDay { get; set; }
[QueryDbField(Template = "(FirstName LIKE {Value} OR LastName LIKE {Value} OR PreferredName LIKE {Value})", ValueFormat = "%{0}%", Field = "ID")]
public string NameSearch { get; set; }
[QueryDbField(Template = "(FirstName LIKE {Value} OR LastName LIKE {Value} OR PreferredName LIKE {Value} OR Department.Name LIKE {Value} OR Title.Name LIKE {Value})", ValueFormat = "%{0}%", Field = "ID")]
public string BasicSearch { get; set; }
[QueryDbField(Template = "({Field} LIKE {Value})", Field = "EmployeeTypeName", ValueFormat = "%{0}%")]
public string EmployeeTypeSearch { get; set; }
[QueryDbField(Template = "({Field} LIKE {Value})", Field = "DepartmentName", ValueFormat = "%{0}%")]
public string DepartmentSearch { get; set; }
[QueryDbField(Template = "({Field} LIKE {Value})", Field = "TitleName", ValueFormat = "%{0}%")]
public string TitleSearch { get; set; }
}
Support for wildcard custom field lists was added in this commit where you can specify all fields of the primary or joined table by adding a .* suffix, e.g:
?fields=id,departmentid,department,employee.*
It essentially serves as a substitute placeholder which will be replace it with all fields in the specified table.
This change is available from v4.0.55 that's now available on MyGet.

EF Code First - Many To Many

I have a problem with devising a many to many relationship in code first. EF is creating the Junction table and associating the Fk's as I would expect, however when i try to access the User's MailingList collection, there are no entries.
I've implemented test data on Initialise via Seeding, the data is al present in the database.
I think the problem lies with the constructors for Users and MailingLists, but I'm uncertain. I want to be able to navigate the navigational property of User.MailingLists.
var user = db.Users.Find(1);
Console.WriteLine("{0}", user.EmailAddress); //This is Fine
Console.WriteLine("{0}", user.Address.PostCode); /This is Fine
foreach (MailingList ml in user.MailingLists) // this is 0
{
Console.WriteLine("{0}", ml.Name);
}
My model is below:-
public class User : IEntityBase
{
public User()
{
MailingLists = new List<MailingList>();
}
public int Id { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string EmailAddress { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public virtual Address Address { get; set; }
public ICollection<MailingList> MailingLists { get; set; }
}
public class MailingList : IEntityBase
{
public MailingList()
{
Users = new List<User>();
}
public int Id { get; set; }
public string Name { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public ICollection<User> Users { get; set; }
}
public class Address : IEntityBase
{
public int Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
}
Any suggestions welcome.
You are neither eager loading the MailingList entries with the query, nor fulfulling the requirements for a lazy loading proxy so there is no way EF can populate the collection.
To allow lazy loading, change the MailingList property to be virtual to allow the EF proxy to override it.
To use eager loading, use Include() (an extension method in System.Data.Entity) in the query to specify that the MailingList should be loaded.

Entity Framework - Update complex entities

I'm using EF5.0 (database first) and trying to Update "Company" entity which is a complex type, it contains "Address" entity as navigation property.
I receive a Company DTO object from UI and I map it, using AutoMapper, to Entity object and call objectContext.Save() for saving.
Problem am facing is, "Company" entity values are getting saved but not the "Address" entity. Below are the each object details-
public class CompanyDto
{
public int Id { get; set; }
public string Name { get; set; }
public AddressDto Address { get; set; }
}
with AddressDto as -
public class AddressDto : IDto
{
public int Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string PostCode { get; set; }
}
Company Entity (generated by EF - database first)
public partial class tblCompany
{
public tblCompany()
{
this.tblAddresses = new HashSet<tblAddress>();
}
public int ID { get; set; }
public string CompanyName { get; set; }
public virtual ICollection<tblAddress> tblAddresses { get; set; } //navigation property
}
with Address entity is as follows -
public partial class tblAddress
{
public int ID { get; set; }
public int CaseID { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
public virtual tblCase tblCase { get; set; }
}
AutoMapper mapping configuration for converting from DTO to entity
Mapper.CreateMap<CompanyDto, tblCase>()
.ForMember(x => x.ID, opt => opt.MapFrom(cd => cd.Id))
.ForMember(x => x.CompanyName, opt => opt.MapFrom(cd => cd.Name))
.AfterMap((s, d) => d.tblAddresses.Add(new tblAddress
{
AddressLine1 = s.Address.Street,
CaseID = s.Id,
City = s.Address.City,
PostCode = s.Address.PostCode
}));
public void Update(CompanyDto company)
{
//TO DO: check if AutoMapper could map address as well.
var companyDao = Mapper.Map<CompanyDto, tblCase>(company);
_companyRepository.Update(companyDao);
_unitOfWork.Save();
}
Thanks in advance
Sai

Resources