Entity Framework 6- dbset Find with composite primar key does not work - find

I have this table with two columns that comprise the primary key. When I try to find the record can not be found.
Table:
public partial class CITVENDBILL
{
public string VNDR_NO { get; set; }
public string VINV_NO { get; set; }
[Key, Column(Order = 0)]
public string OUR_INV { get; set; }
[Key, Column(Order = 1)]
public decimal REL_NO { get; set; }
public string VSHP_NO { get; set; }
}
Find:
CITVENDBILL cITVENDBILL = db.CITVENDBILLS.Find(id,rel);
I have checked and my syntax and method is correct. Can anyone help?
Des anyone know how you can debug what is EF6 looking for?
Many thanks.

Do anyone know how you can debug what is EF6 looking for
Use SQL Profiler and check the SQL Statement which has been executed by Entity Framework. Once you have it, you can execute it yourself in your SQL Server to understand why nothing is found.

Related

Entity Framework Add-Migration cannot detect changes that I made on foreign key

I am using Entity Framework Code First approach. I was able to use Add-Migration to automatically detect when I added new table into my context. But, when I change the foreign key on one of the models, Add-Migration unable to detect the changes and generate the codes to update the foreign key.
Here is my Model
public class PhoneInfo
{
[Key]
[Column(Order = 2)]
public String ID { get; set; }
[Required]
[Key]
[ForeignKey("Contact"), Column(Order = 1)]
public String UserID { get; set; }
[Required]
[Key]
[ForeignKey("Contact"), Column(Order = 0)]
public String ContactID { get; set; }
public String Value { get; set; }
public DateTime LastChanged { get; set; }
public String Type { get; set; }
public int Order { get; set; }
public bool IsDeleted { get; set; }
public DateTime DeletedDate { get; set; }
public virtual Contact Contact { get; set; }
}
I am updating the Column(Order = 1) below
[ForeignKey("Contact"), Column(Order = 1)]
Is there any ways to make Add-Migration automatically generate codes that I needed to update the database?
for migrations you need to execute two commands in package manager console:
1. Add-Migration AddOrder1ContactFK
2. Update-Database
Set AutomaticMigrationsEnabled property to true which is defined in the constructor of the Configuration.cs. Its default value is false when you first enable the migrations. Then rebuilt your solution and try update-database once more.

Entity Framework Key Name on Parent Entity

I have classes that look like this:
public class Signer
{
[Key, Column(Order = 0)]
public Guid EntityUUID { get; set; }
[Key, Column(Order = 1)]
public Guid SignerUUID { get; set; }
[ForeignKey("EntityUUID")]
public virtual User User { get; set; }
}
public class User
{
[Key]
public int Id { get; set; }
public Guid? EntityUUID { get; set; }
public virtual List<Signer> Signers { get; set; }
}
When trying to create the migration for this, EF is trying to make the User.Id column the parent of the relationship with Signer, which fails because they are of different types. What I need to happen is have User.EntityUUID be the parent for the relationship, but I can't find anything that allows me to set the parent side of the relationship. I looked at InverseProperty attribute, but that doesn't seems to help my situation. Annotations would be my preferred fix. Any ideas?
EDIT:
A co-worker claims this isn't possible currently with EF, anyone able to confirm?
Found this, looks like it is coming in EF 7 but not currently available.
Alternate Keys in Entity Framework

EntityFramework 6.1 Add Method

I have a very simple problem. Always use like this, but now not working, why i dont know.
I'm working on MVC 4 and Entity Framework 6.1.
I have sql table like picture below which name is Kategori,
Translation: KategoriID -> CategoryID, KategoriIsmi -> Category, UstKategoriId -> ParentCategoryID
KategoriID column has also, Primary Key and Identity Specification YES (Identity Increment 1, Seed 1)
And this is my Kategori Model class
public class Kategori
{
[Key]
public byte? KategoriID { get; set; }
[Required(ErrorMessage = "Please insert category name")]
public string KategoriIsmi { get; set; }
public byte? UstKategoriID { get; set; }
}
And my save code with EntityFramework
public void AddNewItem(Kategori item)
{
using (EmlakCMSContext _ent = new EmlakCMSContext())
{
_ent.Kategori.Add(item);
_ent.SaveChanges();
}
}
When I run this code
Income data (for save in db)
I have a error. And I write code, watch the error in IntelliTrace.
Error Translate: KategoriID alanı gereklidir -> CategoryID field is required.
But KategoriID field have set auto increment true.
How can i solve this problem? Thanks.
It's hard to tell as the error message is not in English. However, your primary key should not use a nullable data type. Change this:
public byte? KategoriID { get; set; }
To this:
public byte KategoriID { get; set; }
You may also need to tell entity framework that the column is an IDENTITY column:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public byte KategoriID { get; set; }

Entity framework two-way relationship not loading includes

This is making me feel like an idiot. Entity Framework is supposed to be fairly simple, yet I can't sort this out myself and clearly I've got a fundamental misunderstanding. I hope it doesn't turn out to be an idiot-question - sorry if it is.
Three code-first objects, related to one another.
public class Schedule
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public virtual ICollection<Charge> Charges { get; set; }
}
public class Charge
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public decimal Rate { get; set; }
public Type Type { get; set; }
}
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
}
When I query this, I want all related types, so:
Schedule currentSchedule = _Context.Schedules
.Include("Charges.Type")
.Where(cs => cs.Start < dateWindow && cs.End > dateWindow)
.First();
In C#, this has been working fine.
The problem arises because we're not stopping at C#, but passing the data onto a javascript library called Breeze with smooths out data operations at the client end. Breeze has a bug/feature which demands that EF relationships between objects be specified at BOTH ENDS. So when I do my query above, I don't end up with any Types, because their relationship with Charge isn't directly specified.
So I change it to this:
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public virtual Charge Charge { get; set; }
}
Because virtual is a navigation property, so that should enable Breeze should now to go both ways across the relationship without changing the data structure. But EF doesn't like this. It tells me:
Unable to determine the principal end of an association between the
types 'Core.Charge' and 'Core.Type'. The principal end of this
association must be explicitly configured using either the
relationship fluent API or data annotations
Fair enough. I can see how this could be confusing. Now, my understanding is that if you define a foreign key in a dependent class, it has to be that classes' primary key. So we change it to:
public class Type
{
[Key, ForeignKey("Charge"), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public virtual Charge Charge { get; set; }
}
And that seems to work but ... it's stopped loading any Type information when you ask for a schedule. Messing around with the includes doesn't seem to do anything at all.
What's going on, and what have I done wrong?
You haven't only added a navigation property (Type.Charge) to an existing model/relationship. Instead you have changed the relationship completely from a one-to-many to a one-to-one relationship because by default if a relationship has only one navigation property EF assumes a one-to-many relationship. With your change you have configured a one-to-one relationship.
Those relationships have different foreign keys: The original one-to-many relationship has a separate foreign key in the Charge table (probably named Type_RowId or similar). Your new relationship has the foreign key at the other side in table Type and it is the primary key RowId. The Charges you are loading together with the Schedule probably don't have any related Type with the same primary key, hence no Type is loaded.
If you actually want to reproduce the old (one-to-many) relationship with just a navigation property at the other side you must add a collection to Type instead of a single reference:
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public virtual ICollection<Charge> Charges { get; set; }
}
Are you sure that you want to put ForeignKey on RowId, I think you may want to define some relationship like this
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public int ChargeId { get; set; }
[ForeignKey("ChargeId")]
public virtual Charge Charge { get; set; }
}

Table Per Hierarchy & Inherited Relationships

I'm using Entity Framework 5, targeting .Net 4.5. For the life of me I can't figure out what I'm doing wrong that's causing the following error while trying to work with Table Per Hierarchy and Navigation columns:
Invalid column name 'Game_Category'.
Invalid column name 'Game_Value'.
Invalid column name 'Type_Category'.
Invalid column name 'Type_Value'.
Here's the abstract base class (note the composite PK on Category and Value):
[Table("Dictionary")]
public abstract class Lookup
{
[Key, Column(Order = 0)]
[StringLength(50)]
public string Category { get; set; }
[StringLength(100)]
public string ExtendedValue { get; set; }
[Required]
public bool IsActive { get; set; }
[Required]
[StringLength(50)]
public string Key { get; set; }
[Key, Column(Order = 1)]
public int Value { get; set; }
}
Followed by two subclasses that add no additional columns...
public class Game : Lookup {}
public class SetType : Lookup {}
Here's the class with Navigation properties to Game and SetType...
public class CardSet
{
[Required]
[StringLength(10)]
public string Abbreviation { get; set; }
public virtual Game Game { get; set; }
[Required]
public int GameId { get; set; }
[Key]
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
public DateTime ReleaseDate { get; set; }
public virtual Lookup Type { get; set; }
[Required]
public int TypeId { get; set; }
}
From my data context...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Lookup>()
.Map<Game>(l => l.Requires("LookupType").HasValue("Game"))
.Map<SetType>(l => l.Requires("LookupType").HasValue("Set Type"));
base.OnModelCreating(modelBuilder);
}
The lookup table has a discriminator column named LookupType. I've read through several tutorials on table/inheritance. The other two - TPT and TPC using similarly built objects were a cinch. While I understand the errors above - that it's looking for FK columns by convention, I don't understand what I'm doing wrong or missing that's causing it to look for those columns. I've tried placing ForeignKey attributes over the GameId and TypeId properties, but then I get errors about dependent/principal relationship constraints and I'm not sure how to specify the category as an additional foreign key.
I have yet to find a tutorial on table/inheritance that goes over navigation properties as I'm using them. Any help would be greatly appreciated, this has been driving me nuts for over an hour.
Update:
I believe the problem lies in the use of Category as part of the key. The CardSet doesn't have two properties for the category of "Game" for that lookup or the category for "Set Type" for that lookup. I tried creating these properties but that didn't work. Is it possible to set those using the Fluent API? I've made about a dozen attempts so far without any luck.
I think that EF does not "like" the construct modelBuilder.Entity<Lookup>() to map the two sub classes. This should help:
modelBuilder.Entity<Game>()
.Map(l => l.Requires("LookupType").HasValue("Game"));
modelBuilder.Entity<SetType>()
.Map(l => l.Requires("LookupType").HasValue("Set Type"));