Error comes as a {"Invalid object name 'dbo.TableName'."} - entity-framework

I'm using Entity Framework and MVC3,
I have used Model First approch...
I have used Company as a Base class and I have inherited the Lead Class from it.
When I run the application its gives an error...
This is Base Class
using System;
using System.Collections.Generic;
namespace CRMEntities
{
public partial class Company
{
public int Id { get; set; }
}
}
This is Lead Class (Child)
using System;
using System.Collections.Generic;
namespace CRMEntities
{
public partial class Lead : Company
{
public Lead()
{
this.Status = 1;
this.IsQualified = false;
}
public Nullable<short> Status { get; set; }
public Nullable<bool> IsQualified { get; set; }
}
}
I have added the controller,and in index view I have added this code...
public class Default1Controller : Controller
{
private CRMWebContainer db = new CRMWebContainer();
//
// GET: /Default1/
public ViewResult Index()
{
return View(db.Companies.OfType<Lead>().ToList());
}
}
This is DB and Model ...
Its giving the inner error -
{"An error occurred while executing the command definition. See the
inner exception for details."} {"Invalid object name
'dbo.Companies'."}

Do you have a Companies table or Company table in your database. It looks like you have a Mapping issue. Entity Framework will make some guesses as to how it pluralizes entity names by default.

Related

Entity Framework Core 3 : Type must match overridden member

I have the following two dbcontexts in my Entity Framework Core solution. The OrganisationContext derives from SagitarriContext. I am overiding the base property DbSet<Person> Person. I am getting the following error in the derived class:
Error CS1715
'OrganisationContext.Person': type must be 'DbSet' to match overridden member 'SagitarriContext.Person'
DbContext
namespace Genistar.Data.DbContexts.Interfaces
{
public class SagitarriContext : DbContext, ISagitarriContext
{
public SagitarriContext();
public SagitarriContext(DbContextOptions<SagitarriContext> options);
protected SagitarriContext(DbContextOptions options);
public virtual DbSet<Person> Person { get; set; }
}
}
namespace Genistar.Data.DbContexts
{
public class OrganisationContext : SagitarriContext
{
private readonly ITimeProvider _timeProvider;
private readonly IUserContextResolverFactory _userContextResolver;
public OrganisationContext(DbContextOptions options)
: base(options)
{
}
public OrganisationContext(DbContextOptions options, ITimeProvider timeProvider, IUserContextResolverFactory userContextResolver)
: base(options)
{
_timeProvider = timeProvider;
_userContextResolver = userContextResolver;
}
public override DbSet<Person> Person { get; set; }
}
}
namespace Genistar.Data.DbContexts.Interfaces
{
public interface ISagitarriContext
{
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
DbSet<TQuery> Set<TQuery>() where TQuery : class;
public DatabaseFacade Database { get; }
DbSet<Person> Person { get; set; }
}
}
Usings
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Genistar.Data.DbContexts;
using Genistar.Data.Models;
using Genistar.Organisation.Models.Representative;
using Genistar.Organisation.Models.Unregistered;
using Genistar.Organisation.Models.User;
using Person = Genistar.Organisation.Models.DataModels.Person;
using PersonNote = Genistar.Organisation.Models.DataModels.PersonNote;
using Genistar.Security.Context;
using Genistar.Security.Utility;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
You are not in the same namespace, so the Person class used in DbSet<Person> might be a different one in Genistar.Data.DbContexts.Interfaces and Genistar.Data.DbContexts. Also, we don't see the usings, so there might be an error there.

Entity Framework 6.0 - Evaluation of method System.Linq.Queryable.Whewre() requires use of the static field

I am using Entity Framework 6.0 with .NET framework 4.5 inside a SharePoint 2013 project, to get data from a view in a database based on a specific condition.
My Context.cs file looks like this:
namespace Clients
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class Clients_ReqsEntities : DbContext
{
public Clients_ReqsEntities()
: base("name=Clients_ReqsEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<ClientInfo> ClientInfo { get; set; }
}
}
And my ClientInfo.cs file looks like this:
namespace Clients
{
using System;
using System.Collections.Generic;
public partial class ClientInfo
{
public string ClientTitle { get; set; }
public string ClientID { get; set; }
public string ClientUNumber { get; set; }
}
}
I am trying to get data from this view based on the ClientUNumber, using this query:
string anyValue = "something";
var client = (context.ClientInfo.Where(c => c.ClientUNumber.Trim() == anyValue)).FirstOrDefault();
The returned value is always "null", however if I run that line of code in Watch window, I am getting this error:
Evaluation of method System.Linq.Queryable.Where() requires use of the static field System.Data.Entity.Core.Objects.ObjectQuery`1[Clients.ClientInfo].MergeAsMethod, which is not available in this context.
I tried using this query too:
(from c in context.ClientInfo where c.ClientUNumber.Trim() == anyValue select c).FirstOrDefault();
But I am getting the same error.
Some posts suggest to use ToList(), but this will get all records from the DB, and I keep getting Evaluation Timedout. So I don't think this is the right approach. PS: the view has 7k records.
Any help is appreciated.

System.Data.SqlClient.SqlException: Invalid object name 'dbo.__TransactionHistory'

I get the error
"System.Data.SqlClient.SqlException: Invalid object name
'dbo.__TransactionHistory'."
when I try creating a new dbcontext using the TransactionContext in EF 6.1.3. It seems like a bug where it's using the transactioncontext API before the DBMigrator/Initializer even has a chance to create it since these operations are done within a transaction.
Below is the code that replicates the problem
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new SomeDbContext().Database.Initialize(false);
}
public class Person
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());
}
}
[DbConfigurationType(typeof(MyConfiguration))]
public class SomeDbContext : DbContext
{
static SomeDbContext()
{
Database.SetInitializer(new DropCreateDatabaseAlways());
}
public SomeDbContext()
: base(#"Data Source=.;Initial Catalog=SomeDbContext;Integrated Security=True;MultipleActiveResultSets=True;Connect Timeout=1;")
{
}
public virtual DbSet People { get; set; }
}
}
}
I ended up doing two things.
Manually run the SQL CREATE TABLE [dbo].[__TransactionHistory] (
[Id] [uniqueidentifier] NOT NULL,
[CreationTime] [datetime] NOT NULL,
CONSTRAINT [PK_dbo.__TransactionHistory] PRIMARY KEY ([Id])
Creating a CommitFailureHandler that overrides the BeganTransaction to not call the base method until the table has been created

seed method not called with EntityFramework CodeFirst

I've been struggling on and off with this problem since 4.1 (now I'm on 4.3). It seems to me that to get the seed method called, all I should have to do is the following:
1) Create an empty data catalog on sqlserver
2) Execute the code below:
Database.SetInitializer(new DropCreateDatabaseAlways<SiteDB>());
I have my SiteDB defined as follows:
public class SiteDBInitializer :
DropCreateDatabaseAlways<SiteDB>
{
protected override void Seed(SiteDB db)
{
... (break point set here that never gets hit)
I feel like I must be missing something very simple because this creates my tables, but does never calls the seed method.
To Make this more clear, here is a full example that includes all the code. When I run it, seed never gets called:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Data.Entity;
namespace ConApp
{
internal class Program
{
private static void Main(string[] args)
{
Database.SetInitializer(new SiteDBInitializer());
using (var db = new SiteDB())
{
var x = db.Customers;
}
}
}
public class SiteDB : DbContext
{
public DbSet<Customer> Customers { get; set; }
}
public class Customer
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public string LastName { get; set; }
}
public class SiteDBInitializer :
DropCreateDatabaseAlways<SiteDB>
{
protected override void Seed(SiteDB db)
{
db.Customers.Add(new Customer() {LastName = "Kellner"});
db.Customers.Add(new Customer() {LastName = "Jones"});
db.Customers.Add(new Customer() {LastName = "Smith"});
db.SaveChanges();
}
}
}
You need call Database.SetInitializer(new SiteDBInitializer()); instead.
I looked at all the answers for that, nothing really works, and I wonder if that's a Microsoft bug for not calling the Seed method when DB does not exists.
The only code that worked, was to actually make the class call the seed if DB does not exists:
Context class:
class AlisDbContext : DbContext
{
public class MyContextFactory : IDbContextFactory<AlisDbContext>
{
public AlisDbContext Create()
{
return new AlisDbContext("CompactDBContext");
}
}
public AlisDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
Database.SetInitializer(new AlisDbInitializer(this));
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<AlisDbContext>());
}
public DbSet<SavedCredentials> SavedCredentialses { get; set; }
}
Then AlisDbInitializer need to check and call the seed method like:
public AlisDbInitializer(AlisDbContext alisDbContext)
{
if (!alisDbContext.Database.Exists())
{
Seed(alisDbContext);
}
}

Schema invalid and types cannot be loaded because the assembly contains EdmSchemaAttribute

Getting the following error:
Schema specified is not valid. Errors:
The types in the assembly 'x, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' cannot be loaded because the assembly contains
the EdmSchemaAttribute, and the closure of types is being loaded by
name. Loading by both name and attribute is not allowed.
What does this error mean exactly?
I'm trying to shoe-horn into my application an EF model from an existing database.
Before this application was based on CodeFirst and using the repository pattern but for the life of me I can't get this working.
Before I had:
public class BaseModelContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
}
But in a EF model-first scenario (one where tables already exist in the db), I had to remove these as it didn't seem to like having a repository pattern on DbSet properties.
So I stripped these out, and the repository can then use repository on the classes already defined on the .designer.cs context class (the EF model). This has the EdmSchemaAttribute set inside the generated code.
So how do I get my repository pattern to work in the model-first scenario? What does the above error mean exactly?
EDIT
Added new code:
public class BaseModelContext : DbContext
{
// public DbSet<Location> Locations { get; set; }
public BaseModelContext(string nameOrConnection)
: base(nameOrConnection)
{
}
public BaseModelContext()
{
}
}
public class VisitoriDataContext : BaseModelContext
{
public VisitoriDataContext()
: base("visitoriDataConnection")
{
}
}
public interface IVisitoriDataContextProvider
{
VisitoriDataContext DataContext { get; }
}
public class VisitoriDataContextProvider : IVisitoriDataContextProvider
{
public VisitoriDataContext DataContext { get; private set; }
public VisitoriDataContextProvider()
{
DataContext = new VisitoriDataContext();
}
}
public class VisitoriRepository<T> : IRepository<T> where T : class
{
protected readonly IVisitoriDataContextProvider _ctx;
public VisitoriRepository(IVisitoriDataContextProvider ctx)
{
_ctx = ctx;
}
public T Get(int id)
{
return _ctx.DataContext.Set<T>().Find(id);
}
}
public interface ILocationRepo : IRepository<Location>
{
IEnumerable<Location> GetSuggestedLocationsByPrefix(string searchPrefix);
}
public class LocationRepo : VisitoriRepository<Location>, ILocationRepo
{
public LocationRepo(IVisitoriDataContextProvider ctx)
: base(ctx)
{
}
public IEnumerable<Location> GetSuggestedLocationsByPrefix(string searchPrefix)
{
return Where(l => l.name.Contains(searchPrefix)).ToList();
}
}
The error means that you cannot combine code first mapping (data annotations and fluent API) and EDMX mapping (with EntityObjects!) for entity with the same name. These two approaches are disjunctive.
The rest of your question is not clear.
Btw. building mapping from existing database is called database first not model first.
Decorate the assembly containing the GILayerModel type with [assembly: EdmSchema] attribute.
In my case, I had a class that derived from an entity (code-first class) in another assembly, and I was adding an instance of this class to the DBContext:
in DBEntities project:
public class GISLayer
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int GISLayerId { get; set; }
[StringLength(200)]
public string LayerName { get; set; }
public List<GISNode> Nodes { get; set; }
}
in the second assembly:
public class GISLayerModel : DBEntities.GISLayer
{
public new List<GISNodeModel> NodesModel { get; set; }
}
and the cause of error:
[WebMethod]
public void SaveGISLayers(GISLayerModel[] layers)
{
using (DBEntities.DBEntities db = new DBEntities.DBEntities())
{
foreach (var l in layers)
{
if (l.GISLayerId > 0)
{
db.GISLayers.Attach(l); //attaching a derived class
db.Entry(l).State = System.Data.EntityState.Modified;
}
else
db.GISLayers.Add(l); //adding a derived class
SaveGISNodes(l.NodesModel.ToArray(), db);
}
db.SaveChanges();
}
}
So, I used AutoMapper to copy properties of derived class to a new instance of base class:
DBEntities.GISLayer gl = AutoMapper.Mapper.Map<DBEntities.GISLayer>(l);
if (gl.GISLayerId > 0)
{
db.GISLayers.Attach(gl);
db.Entry(gl).State = System.Data.EntityState.Modified;
}
else
db.GISLayers.Add(gl);
That solved the problem.