Entityframework Table name is appended with 'es' on savechanges - c#

I'm facing a strange error using entityframe work. I have model entity called "UserInfo" and my DB table name is also "UserInfo". However when i'm called the savechanges() in entity frame work. i'm getting a strange error like Invalid object name 'dbo.UserInfoes'.
I searched the entire solution, to see whether i miss typed anything to "UserInfoes" and i didnt find anything. Please help me to solve this issue. How "es" is append along with it?
[Table("UserInfo")]
public class UserInfo
{
public int Id { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public int Field5 { get; set; }
}

You need to disable the Pluralize Table Names for the LINQ to SQL designer.
Here is the steps
http://msdn.microsoft.com/en-us/library/bb384507.aspx

It is probably to do with settings. EF will pluralise table names automatically under some circumstances. The problem may be your entity name: Userinfo -> Userinfoes. It looks like you are using code first so look at your entity settings.

Related

C# LINQ Query Hanging

I'm working to create a c# application, and in a portion of the application; I'm looking to bring in a .csv to a data table; and then basically loop through each row and query a database to see if the data exists.
I'm testing a LINQ query; but I can't seem to get it to run and display anything. I have the following code setup to run below:
I have the database added and the connection tests succesfully; I have the classes setup. I've been following some courses on pluralsight to test; and I'm not sure what exactly I am doing wrong or missing.
Also as a note; the table name is actually ERP.PartTran, and not PartTran, but I wasn't succesful in setting that up for the db context; could that be why?
EDIT: Code added; images removed
public class EpiDB : DbContext
{
public DbSet<Tran> PartTran { get; set; }
}
public class Tran
{
public int TranNum { get; set; }
public string TranReference { get; set; }
public string PartNum { get; set; }
}
private static void QueryPartTran()
{
var db = new EpiDB();
int tranref = 4650374; //lookup number
var query = from Tran in db.PartTran
where Tran.TranNum == tranref
orderby Tran.TranNum
select Tran;
foreach (var Tran in query)
{
Debug.Print(Tran.PartNum);
}
}
If you have an existing database schema, the first thing to avoid soft exceptions is to disable schema creation/migration in EF. By default when EF connects to a database and goes to resolve the schema, if it comes across a table that it cannot resolve, it will create it. The clue I see that might be happening in this case is when you say the table is called [ERP].PartTran. I suspect you may find that your database has a new empty table called [dbo].Tran. (assuming SQL Server)
To disable schema creation:
In your Db Context constructor
public EpiDB()
{
Database.SetInitializer<EpiDB>(null);
}
This may go a long ways to identifying any bad schema assumptions that EF is making by convention. Jim's answer would be along the lines of where I would believe your problem will lie.
Entities should map relatively closely, if not identically to your table. Renaming an entity or properties to differ from the table to clarify it in code is fine, but you need to be sure that when you do this, you give EF enough information about your schema so that it can resolve the table correctly. If your table is named "PartTran" and your DbSet instance is named "PartTran", why would you want to name the entity "Tran" rather than "PartTran"?
If your application schema is "ERP" then you can avoid needing to specify the schema name on each entity by adding the following to your DbContext.OnModelCreating():
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("ERP");
// ...
}
Otherwise, if you are using multiple schemas then you will need to explicitly map the schema to use with a [Table] attribute or ToTable("{tableName}", "{SchemaName}") in EntityTypeConfig / modelBuilder config.
Next, ensure that your entity fields match the appropriate fields in the table. You don't need to map every field if you don't need them, but at a minimum you do need to map the Primary Key. On a guess from the PartTran entity, I'm guessing you're either missing something like a PartTranId column, or the PK is a composite key using the PartNum and TranNum columns. If you have a PartTranId or similar PK, add it to the entity along with a [Key] attribute. If the PK is a composite:
public class PartTran
{
[Key, Column(Order = 1)]
public int TranNum { get; set; }
public string TranReference { get; set; }
[Key, Column(Order = 2)]
public string PartNum { get; set; }
}
This should give you a few ideas to check out against your code base... To go further it would help to amend your question to include the related tables and any entities you have tried creating so far. Something like "PartTran" looks like a joining table for a many-to-many relationship between a "Part" table and a "Tran"(saction?) table. If that is the case there are a number of options how you can efficiently wire this up in EF to get the data out the way you want.
Try this:
public class EpiDB : DbContext
{
public DbSet<Tran> PartTran { get; set; }
}
[Table("PartTran", Schema = "ERP")]
public class Tran
{
public int TranNum { get; set; }
public string TranReference { get; set; }
public string PartNum { get; set; }
}
And maybe even:
public class EpiDB : DbContext
{
public DbSet<Tran> PartTran { get; set; }
}
[Table("PartTran", Schema = "ERP")]
public class Tran
{
[Key] // Is this your primary key field?
public int TranNum { get; set; }
public string TranReference { get; set; }
public string PartNum { get; set; }
}

Why EF navigation property return null?

I have two model
1)
public class Indicator
{
public long ID { get; set; }
public string Name { get; set; }
public int MaxPoint { get; set; }
public string Comment { get; set; }
public DateTime DateChanged { get; set; }
public DateTime DateCreated { get; set; }
public virtual IList<CalculationType> CalculationTypes { get; set; }
public virtual IList<TestEntity> TestEntitys { get; set; }
public virtual IndicatorGroup IndicatorGroup { get; set; }
}
2)
public class CalculationType
{
public long ID { get; set; }
public string UnitName { get; set; }
public int Point { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateChanged { get; set; }
public virtual Indicator Indicator { get; set; }
public virtual IList<Сalculation> Calculations { get; set; }
}
I executing this code
var indicator = DataContext.Indicators.FirstOrDefault(i => i.ID == indicatorID);
var test = DataContext.CalculationTypes.FirstOrDefault();
first line return null on navigation property CalculationTypes
Second line return empty collection. Why?
UPDATE
snapshot database
project link https://github.com/wkololo4ever/Stankin
added Calculation
public class Сalculation
{
public long ID { get; set; }
public virtual CalculationType CalculationType { get; set; }
public virtual ApplicationUser Creator { get; set; }
}
1) Is Lazy Loading enabled? If not, you need to explicitly load your navigation properties with the '.Include' syntax.
2) Are you sure EF should be able to detect that relation? Did you use Code First or Database First?
Edit: 3) Are you sure there is data in your database and that the foreign key from Indicator to IndicatorGroup has a value for that specific record? I am saying this because the value "null" is valid if there is simply no data.
P.S. If you do not see a foreign key on Indicator called "IndicatorGroupId", there might be an "IndicatorId" on the table "IndicatorGroup", in which case - going from the names you provided - your database is misconfigured and you will need to use fluent syntax or data attributes to instruct EF on how to make the foreign keys.
Try this:
DbContext.Configuration.ProxyCreationEnabled = true;
DbContext.Configuration.LazyLoadingEnabled = true;
If DbContext.Configuration.ProxyCreationEnabled is set to false, DbContext will not load child objects for some parent object unless Include method is called on parent object. Setting DbContext.Configuration.LazyLoadingEnabled to true or false will have no impact on its behaviours.
If DbContext.Configuration.ProxyCreationEnabled is set to true, child objects will be loaded automatically, and DbContext.Configuration.LazyLoadingEnabled value will control when child objects are loaded.
I think this is problem:
Edit: 3) Are you sure there is data in your database and that the
foreign key from Indicator to IndicatorGroup has a value for that
specific record? I am saying this because the value "null" is valid if
there is simply no data.
P.S. If you do not see a foreign key on Indicator called
"IndicatorGroupId", there might be an "IndicatorId" on the table
"IndicatorGroup", in which case - going from the names you provided -
your database is misconfigured and you will need to use fluent syntax
or data attributes to instruct EF on how to make the foreign keys.
Try to this and make sure foreign key is corrected.
public class CalculationType
{
public long ID { get; set; }
public string UnitName { get; set; }
public int Point { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateChanged { get; set; }
[ForeignKey("IndicatorID")]
public string IndicatorId { get; set; } //this is the foreign key, i saw in your database is: Indicator_ID, avoid this, rename it to IndicatorID or IndicatorId
public virtual Indicator Indicator { get; set; }
public virtual IList<Сalculation> Calculations { get; set; }
}
Same behavior, but different root cause than selected answer:
Navigation property can also be null if you turned off myContext.Configuration.AutoDetectChangesEnabled
Very obvious, but this got me when I was implementing some performance improvments.
Check this out: Navigation Property With Code First . It mentions about why navigation property is null and the solutions of it.
By default, navigation properties are null, they are not loaded by
default. For loading navigation property, we use “include” method of
IQuearable and this type of loading is called Eager loading.
Eager loading: It is a process by which a query for one type of entity
loads the related entities as a part of query and it is achieved by
“include” method of IQueryable.
I experienced this issue, where navigation properites were not loaded, even when the Include statement was present.
The problem was caused by string-comparison differences between SQL Server and EF6 using .NET. I was using a VARCHAR(50) field as the primary key in my customers table and also, as a foreign key field in my audit_issues table. What I did not realize was that my keys in the customers table had two additional white space characters on the end; these characters were not present in my audit_issues table.
However, SQL Server will automatically pad whitespace for string comparisons. This applies for WHERE and JOIN clauses, as well as for checks on FOREIGN KEY constraints. I.e. the database was telling me string were equivalent and the constraint passed. Therefore I assumed that they actually were exactly equal. But that was false. DATALENGTH of one field = 10, while the DATALENGTH of the other = 8.
EF6 would correctly compose the SQL query to pull the foreign key related fields and I would see them both in the generated Sql query and in the results. However, EF6 would silently fail when loading the Navigation Properties because .NET does not consider those strings equal. Watch out for whitespace in string-type foreign key fields!.
This article helped me.
In sum :
Install-Package Microsoft.EntityFrameworkCore.Proxies
In Startup.cs
using Microsoft.EntityFrameworkCore;
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<MyDbContext>(builder =>
{
builder.UseLazyLoadingProxies(); // <-- add this
}, ServiceLifetime.Singleton);
This is a variant of Keytrap's answer. Using .NET 6 and EF Core 6, I created a ContextPartials.cs for any custom configurations that I don't want EF's Scaffold command to overwrite:
Required Package:
Install-Package Microsoft.EntityFrameworkCore.Proxies
Code (ContextPartials.cs):
// NOTE: I am not using the new file-scoped namespace on purpose
namespace DataAccess.Models.MyDatabase
{
// NOTE: This is a partial outside of the generated file from Scaffold-DbContext
public partial class MyDatabaseContext
{
// NOTE: This enables foreign key tables to become accessible
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseLazyLoadingProxies();
}
}

Filling Foreign Key Object in Entity Framework 4

I am using EntityFramework for the first time and maybe this question is so simple...I've used code first method..I have a Class Personnel which looks like this:
public class Personnel
{
public string Id { set; get; }
public int Code { set; get; }
public string Name { set; get; }
public int Type { set; get; }
public JobTitle Title { set; get; }
}
and the JobTitle class:
public class JobTitle
{
public string Id { set; get; }
public int Number { set; get; }
public string Title { set; get; }
public List<Personnel> Personnels { set; get; }
}
which the last property in Personnel Class is a foreign key in personnel table of course..my problem is when I want to retrieve all personnels ( or a personnel ) from DB using lambda expression..the foreign key object is null..the lambda expression is like below:
Context.ContextInstance.Personnels.ToList();
and if I change the expression to this the foreign key object is not null any more.
Context.ContextInstance.Personnels.Include("Title").ToList();
is it the right way??..is there any better way??..I supposed that EF will automatically understand that!!!!..if there are more than 1 FK then I have to use Include for all of them?? please help me to understand.
Thanks
This is due to lazy loading. When you call Context.ContextInstance.Personnels.ToList(); this will fetch all personnel's but Title will not fetch until it get instanced, so make it virtual to get it.
or, you can disable lazy loading by
public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext") {
this.Configuration.LazyLoadingEnabled = false;
}
Doing this will get all related data from context. Using "include" is loading on demand, when you specify properties you want to query.
Virtual keyword allows entity framework runtime create dynamic proxies for your entity classes and their properties, and by that support lazy loading. Without virtual, lazy loading will not be supported, and you get null on collection properties.
If your JobTitle property would be defined as virtual, you wouldn't need to use include.
It's really good explained here: Entity Framework 4.1 Virtual Properties

Fluent NHibernate Relation Without Foreign Key

I'm trying so simplify my problem here, but basically I'm trying to map 2 entities however i don't have a Foreign Key in the database set, since the column could be null. When I try to do an insert on the parent, I'm getting the following error:
object references an unsaved transient instance - save the transient
instance before flushing or set cascade action for the property to
something that would make it autosave.
This is what I have so far:
My entities
public class DocumentDraft
{
public virtual Guid Id { get; set; }
public virtual string Subject { get; set; }
public virtual string ReferenceNo { get; set;}
public virtual DocumentType DocumentType { get; set; }
}
public class DocumentType
{
public virtual short Id { get; set; }
public virtual string Description { get; set; }
}
Mapping
public class DocumentDraftMap : ClassMap<DocumentDraft>
{
public DocumentDraft()
{
// other mappings ...
References(x => x.DocumentType)
.Columns("DocumentTypeId")
.Nullable()
.Not.LazyLoad()
.NotFound.Ignore(); // <-- added this since the value could be null and it throws an error
}
}
I tried specifying Cascade.None() in the mapping, but I'm getting the same result. Basically what happens is that a null value is attempted at being inserted in the DocumentType, and I don't want this (I want to insert null in the parent table, but I don't want to touch the child tables at all, I don't want this to cascade).
I've also tried: .Not.Insert(), but that didn't work either.
I'd appreciate it if someone could help me out on this one.
I guess the property DocumentType is not really null when saving.
It seems there is an instance and without Cascade.All() on the reference it can not be saved.

Map parameter to ignored property in service stack?

I have a DB entity like:-
public class DBThing
{
public int Id { get; set; }
public string Name { get; set; }
}
The Id maps to the DB primary key. I then have a service DTO like:-
public class Thing
{
[IgnoreDataMember]
public int Id { get; set; }
public string Identity { get; set; }
public string Name { get; set; }
}
The Identity field here contains a REST friendly ID like /things/1, made from the DB Id. I had to call it something differennt from Id, because I'm using TranslateTo and it breaks going from Thing to DBThing if the string Id is "" and it tries to map to int Id, such as when a POST occurs.
The problem I have is that my route [Route("/things/{Id}", "PUT")] fails saying it can't find the Id property on Thing. If I remove [IgnoreDataMember] from the class it works fine. I can imagine why this would be (using shared code with ServiceStack serialization internally?) but I can't see how to fix this. I don't want the internal DB numeric Id serialized to the web services if at all possible.
Can anyone help please?
You can use a int? Id which if it's null it doesn't get serialized by default in JSON / JSV Serializers.

Categories

Resources