Retrieving data from the same database with the Identity - mysql

I connected the identity model of my WebApp to my MySQL Database, and modified it like I want to connect.
My question is the next: If I want to get data from tables not used in the Identity but still from the same database, What is the correct way to do it? Should I open a new connection and get the data with a class? Is there a way to implement it in the model?
I attach the code to connect to the database:
public void Configuration(IAppBuilder app)
{
DbConfiguration.SetConfiguration(new MySqlEFConfiguration());
ConfigureAuth(app);
context = new ApplicationDbContext();
}
And my connectionStrings:
<connectionStrings>
<add name="DefaultConnection" connectionString="server=x.x.x.x;uid=user;password=pwd;database=db;port=3306;charset=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
(Sorry if the question is too obvious, I'm starting to develop apps in ASP.NET MVC)

Yes, all you need to do is open the connection when it is required.
So, i assume you did something like this with your MySQL Database connections
public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
{
public void InitializeDatabase(ApplicationDbContext context)
{
if (!context.Database.Exists())
{
// if database did not exist before - create it
context.Database.Create();
}
else
{
// query to check if MigrationHistory table is present in the database
var migrationHistoryTableExists = ((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
string.Format("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{0}' AND table_name = '__MigrationHistory'",
"[Insert your database schema here - such as 'users']"));
// if MigrationHistory table is not there (which is the case first time we run) - create it
if (migrationHistoryTableExists.FirstOrDefault() == 0)
{
context.Database.Delete();
context.Database.Create();
}
}
}}
and your ApplicationDbContext class will be like this
public class ApplicationUser : IdentityUser{}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
static ApplicationDbContext()
{
Database.SetInitializer(new MySqlInitializer());
}
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
Now, to do some queries from database, you need to create an object of ApplicationDbContext
So, your Next Question "Is there a way to implement it in the model?" Yes there is you need to Create a View Model.
public class ItemProduct
{
public int Id {get; set;};
public string Name {get; set;};
}
So, lets say a Product Table exists in your database and we can query on it.
public class HomeController : Controller
{
ApplicationDbContext context = new ApplicationDbContext();
public ActionResult AnyName()
{
List<ItemProduct> lstProducts = new List<ItemProduct>();
var getProducts = (from p in context.Products
select p).ToList();
foreach(var item in getProducts)
{
ItemProduct pro = new ItemProduct()
{
pro.Id = item.Id,
pro.Name = item.Name
};
lstProducts.Add(pro);
}
// So, you have all your Products in ItemProduct Class list.
// Now, return lstProducts to your View to show it on front end
}
}
Hope this answer your question :)

Related

EF6 + MySql + Identity + another DBContext

ASP.NET MVC 5 with EF6 and MySql using Identity 2. I've been doing DBA-like 'bigdata' for quite a few years and now I'm back in the land of code. I understand EF as an architecture but am struggling with my lack of expertise in getting the ground floor laid for my project especially with the MySql wrinkle.
What I have done successfully: Created a project with a MySQLConfiguration, MySqlHistoryContext, and MySqlInitializer, ran a migration to successfully create the tables for Identity, deployed the site to local server and can successfully register a user and log in. GREAT!
Question: I'm lost as far as how to manage two contexts, merge contexts, what ought be my best practice so I can continue to extend Identity objects and add new database tables through POCO models and migrations to the same database and have them work through a context at the controller.
Guidance would be helpful. I believe my issues are in creating the second context which I would prefer use the same connection.
Attached are my class mods from other tutorials and references.
How do I create a new context which would create a new table from a POCO model using a migration??
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
static ApplicationDbContext()
{
Database.SetInitializer(new MySqlInitializer());
}
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Some comments online suggest not needing a MySqlInitializer. I hardcoded the db name so simply "get it working".
public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
{
public void InitializeDatabase(ApplicationDbContext context)
{
if (!context.Database.Exists())
{
context.Database.Create();
}
else
{
var migrationHistoryTableExists = ((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
string.Format("SELECT COUNT(*) FROM [hardcodeddbname].__MigrationHistory"));
if (migrationHistoryTableExists.FirstOrDefault() == 0)
{
context.Database.Delete();
context.Database.Create();
}
}
}
}
public class MySqlConfiguration : DbConfiguration
{
public MySqlConfiguration()
{
SetHistoryContext(
"MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
}
}
public class MySqlHistoryContext : HistoryContext
{
public MySqlHistoryContext(
DbConnection existingConnection,
string defaultSchema)
: base(existingConnection, defaultSchema)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();
}
}

what is the procedure for creating database in windows phone 8?

I am developing an application in widows phone 8,in my application I have to create a database .how can I do this ,I am new to this.please help me out
Well, that depends on what backend you want, if you are going to store small amounts of data I would recommend that you create an xml file in local storage. If you are looking at something more complex, you can use Linq-to-SQL with SQL Server CE.
The code to generate such a database involves creating a DataContext class similar to this:
public class MyDbContext : DataContext
{
public const string MyDbConnString = "isostore:/MyDb.sdf";
public MyDbContext(string pConnString = MyDbConnString) : base(pConnString) { }
public Table<SomeClass1> table1;
public Table<SomeClass2> table2;
}
Then you would create the classes that will function as "tables" like this:
[Table(Name = "MyTable")]
public class SomeClass1
{
[Column(IsPrimaryKey = true, Name = "ID")]
public int Id { get; set; }
[Column(Name = "Name")]
public string Name { get; set; }
}
Lastly in the App.xaml.cs you would place code to create the database in the constructor:
public App()
{
// ... other code
CreateDatabase();
}
private void CreateDatabase()
{
using (var context = new MyDbContext())
{
if (!context.DatabaseExists())
{
context.CreateDatabase();
}
}
}
Note that if you want an in depth explanation of how the classes need to be set up, if you want to create foreign key references for example, you need to look at the MS documentation.
I would recommend starting here.

There is already an open DataReader associated with this Connection which must be closed first + asp.net mvc

I have a mysql database with a table entites with multiple fields in it like entity_title, entity_description, ... . In the table there are also 3 foreign keys user_id, region_id an category_id.
In my Index View I would like to show all the entities in a table (show the title, description, ... , the user name, the region name and the category name).
This is what I do in my Controller:
public ActionResult Index()
{
var model = this.UnitOfWork.EntityRepository.Get();
return View(model);
}
In my Repository I do this:
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
I always get the error Input string was not in a correct format on the last rule (return query.ToList()).
But when I check the _dbSet after the rule IQueryable<TEntity> query = _dbSet; it already gives the error: There is already an open DataReader associated with this Connection which must be closed first.
This probably comes because I want to select from more then one table. But how can I fix this? I tried adding MultipleActiveResultSets=True" to my ConnectionString like this:
<connectionStrings>
<add name="reuzzeCS" connectionString="server=localhost;uid=root;pwd=*****;Persist Security Info=True;database=reuzze;MultipleActiveResultSets=True"" providerName="MySql.Data.MySqlClient" />
But that gave me the error that the keyword doesn't exists, because I work with MySql.Data.MySqlClient ..
The Query executed is:
{SELECT
Extent1.entity_id,
Extent1.entity_title,
Extent1.entity_description,
Extent1.entity_starttime,
Extent1.entity_endtime,
Extent1.entity_instantsellingprice,
Extent1.entity_shippingprice,
Extent1.entity_condition,
Extent1.entity_views,
Extent1.entity_created,
Extent1.entity_modified,
Extent1.entity_deleted,
Extent1.user_id,
Extent1.region_id,
Extent1.category_id
FROM entities AS Extent1}
But when he wants to execute the query and I want to expand the results, I get the error There is already an open DataReader associated with this Connection which must be closed first
EDIT:
My full repository:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace App.Data.orm.repositories
{
// REPO FROM TEACHER
public class GDMRepository<TEntity> where TEntity : class
{
internal GDMContext _context;
internal DbSet<TEntity> _dbSet;
public GDMRepository(GDMContext context)
{
this._context = context;
this._dbSet = _context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return _dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
_dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = _dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entity)
{
if (_context.Entry(entity).State == EntityState.Detached)
{
_dbSet.Attach(entity);
}
_dbSet.Remove(entity);
}
public virtual void Update(TEntity entity)
{
_dbSet.Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
}
}
}
GDMContext class:
using App.Data.orm.mappings;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace App.Data.orm
{
public class GDMContext:DbContext
{
public GDMContext() : base("reuzzeCS") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//REMOVE STANDARD MAPPING IN ENTITY FRAMEWORK
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//REGISTER MAPPERS
modelBuilder.Configurations.Add(new UserMapping());
modelBuilder.Configurations.Add(new PersonMapping());
modelBuilder.Configurations.Add(new RoleMapping());
modelBuilder.Configurations.Add(new EntityMapping());
modelBuilder.Configurations.Add(new MediaMapping());
modelBuilder.Configurations.Add(new BidMapping());
modelBuilder.Configurations.Add(new CategoryMapping());
modelBuilder.Configurations.Add(new AddressMapping());
modelBuilder.Configurations.Add(new RegionMapping());
modelBuilder.Configurations.Add(new MessageMapping());
}
}
}
My entity Model:
public class Entity
{
public Int64 Id { get; set; }
[Required(ErrorMessage = "Title is required")]
[StringLength(255)]
[DisplayName("Title")]
public string Title { get; set; }
[Required(ErrorMessage = "Description is required")]
[DisplayName("Description")]
public string Description { get; set; }
[Required]
public DateTime StartTime { get; set; }
[Required]
public DateTime EndTime { get; set; }
/*[Required(ErrorMessage = "Type is required")]
[StringLength(16)]
[DisplayName("Type")]
public string Type { get; set; }*/
[Required]
public decimal InstantSellingPrice { get; set; }
public Nullable<decimal> ShippingPrice { get; set; }
public Condition? Condition { get; set; }
public Nullable<Int64> Views { get; set; }
[Required]
public DateTime CreateDate { get; set; }
public Nullable<DateTime> ModifiedDate { get; set; }
public Nullable<DateTime> DeletedDate { get; set; }
public Int32 UserId { get; set; }
public Int32 RegionId { get; set; }
public Int16 CategoryId { get; set; }
public virtual User User { get; set; }
public virtual Region Region { get; set; }
public virtual Category Category { get; set; }
//public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<User> Favorites { get; set; }
public virtual ICollection<Bid> Bids { get; set; }
public virtual ICollection<Media> Media { get; set; }
}
public enum Condition
{
New = 1,
Used = 2
}
My Entity Mapping:
internal class EntityMapping : EntityTypeConfiguration<Entity>
{
public EntityMapping()
: base()
{
this.ToTable("entities", "reuzze");
this.HasKey(t => t.Id);
this.Property(t => t.Id).HasColumnName("entity_id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(t => t.Title).HasColumnName("entity_title").IsRequired().HasMaxLength(255);
this.Property(t => t.Description).HasColumnName("entity_description").IsRequired();
this.Property(t => t.StartTime).HasColumnName("entity_starttime").IsRequired();
this.Property(t => t.EndTime).HasColumnName("entity_endtime").IsRequired();
//this.Property(t => t.Type).HasColumnName("entity_type").IsRequired();
this.Property(t => t.InstantSellingPrice).HasColumnName("entity_instantsellingprice").IsRequired();
this.Property(t => t.ShippingPrice).HasColumnName("entity_shippingprice").IsOptional();
this.Property(t => t.Condition).HasColumnName("entity_condition").IsRequired();
this.Property(t => t.Views).HasColumnName("entity_views").IsOptional();
this.Property(t => t.CreateDate).HasColumnName("entity_created").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
this.Property(t => t.ModifiedDate).HasColumnName("entity_modified").IsOptional();
this.Property(t => t.DeletedDate).HasColumnName("entity_deleted").IsOptional();
this.Property(t => t.UserId).HasColumnName("user_id").IsRequired();
this.Property(t => t.RegionId).HasColumnName("region_id").IsRequired();
this.Property(t => t.CategoryId).HasColumnName("category_id").IsRequired();
//FOREIGN KEY MAPPINGS
this.HasRequired(t => t.User).WithMany(p => p.Entities).HasForeignKey(f => f.UserId).WillCascadeOnDelete(false);
this.HasRequired(t => t.Region).WithMany(p => p.Entities).HasForeignKey(f => f.RegionId);
this.HasRequired(t => t.Category).WithMany(p => p.Entities).HasForeignKey(f => f.CategoryId);
//MANY_TO_MANY MAPPINGS
this.HasMany(t => t.Favorites)
.WithMany(t => t.Favorites)
.Map(mc =>
{
mc.ToTable("favorites");
mc.MapLeftKey("entity_id");
mc.MapRightKey("user_id");
});
}
}
Link to stacktrace image!
UPDATE:
base {SELECT
Extent1.entity_id,
Extent1.entity_title,
Extent1.entity_description,
Extent1.entity_starttime,
Extent1.entity_endtime,
Extent1.entity_instantsellingprice,
Extent1.entity_shippingprice,
Extent1.entity_condition,
Extent1.entity_views,
Extent1.entity_created,
Extent1.entity_modified,
Extent1.entity_deleted,
Extent1.user_id,
Extent1.region_id,
Extent1.category_id
FROM entities AS Extent1} System.Data.Entity.Internal.Linq.InternalQuery {System.Data.Entity.Internal.Linq.InternalSet}
Your problem is
I think MySql connector probably doesn't support multiple active result sets and because of that the setting in connection string didn't help you.
So Please try this way instead of your code
Edit :
query.Include("User").Include("Region").Include("Category").ToList();
Let me know, if you get same error after this change.
Update:
I have change some thing for you Please use this code instead of your method
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _dbSet;
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
return orderBy(query.Include("User").Include("Region").Include("Category").ToList()).ToList();
}
else
{
return query.Include("User").Include("Region").Include("Category").ToList();
}
}
Update 2:
It is not about closing connection. EF manages connection correctly. My understanding of this problem is that there are multiple data retrieval commands executed on single connection (or single command with multiple selects) while next DataReader is executed before first one has completed the reading. The only way to avoid the exception is to allow multiple nested DataReaders = turn on MultipleActiveResultSets. Another scenario when this always happens is when you iterate through result of the query (IQueryable) and you will trigger lazy loading for loaded entity inside the iteration.
And stack overflow have lot of peoples got the solutions for your question
1: Entity Framework: There is already an open DataReader associated with this Command
2: How to avoid "There is already an open DataReader associated with this Connection which must be closed first." in MySql/net connector?
3: Error: There is already an open DataReader associated with this Command which must be closed first
and my personal advice for, I think you don't spent more time for this error, because waist of time and energy , and you can do it by using by manual query . So please try different ways.
You don't need split and formatting queries for avoiding input string was not correct format error
You can do this way instead of return query.ToList();
return _dbSet.Users
.Include(x => x.Region)
.Include(x => x.Category).ToList();
I think you can do it by using my above SO link's.
And My main question is :
Entity Framework can support ORM Concept, So why you don't try this way?. You can change the idea for using ORM Concept. It's may be solve this problem. This is a link for that and please see this tutorial
UPDATE
OK, so from your stack trace it looks like the "open DataReader associated ...blah" was a red-herring. Maybe that was visual studio and its intellisense visual debugger thingy trying to show you the values contained in your dbset but a connection was still open or something like that.
To me, it looks like EF's MySqlDatareader is doing its job of enumerating the results and mapping them to POCO's.
Maybe there is a column that is a varchar(..) or something of that sort on a table in your Database, and on your POCO's its mapped property is oftype(Int32). So if there is a an empty string or a value that isn't a number in the database I believe that an Input string was not in a correct format exception should be expected when you try convert a null or empty string value to an Int. Just tried this now to see:
I think the issue is that MySql doesn't support MARS and maybe it also doesn't suport Lazy Loading. While I couldn't find anything official to say this was the case I found a few posts with the same issue as you.
http://www.binaryforge-software.com/wpblog/?p=163
MySQL + Code First + Lazy Load problem !
http://forums.mysql.com/read.php?38,259559,267490
Now up until fairly recently I thought that calling ToList() on an IQueryable would Load the Results into memory and any Navigation properties would not be LazyLoaded, this is not strictly true. While the result will be persisted into Memory any virtual Navigation properties of that result will still be lazy loaded if you try to access them.
On a high level LazyLoading works because entity framework overrides your `virtual' navigation properties and uses its own implementation to load entities from the database.
My guess is that in your View or somewhere else in your code you must be accessing a property that you haven't explicitly loaded using an Include. My guess is that EF may be trying to do this on a single connection and that is why you see:
There is already an open DataReader associated with this Connection which must be closed first
I would turn off Lazyloading by doing the following:
public class GDMContext:DbContext
{
public GDMContext() : base("reuzzeCS")
{
base.Configuration.LazyLoadingEnabled = false;
}
}
Hope this helps.
According to your stack trace, the framework appears to have an issue converting a string to an integer. To quote another SO answer, "EF throws error each time you set a type in the model that is different from the table."
You have a few options.
If you are using a code first approach, I suggest you regenerate your database.
If you are using a "code second" approach (which maps your database tables to POCO classes), then I suggest you regenerate your database.
If you have not had luck with either of the above, you may at least narrow down which column is having the issue by testing each of your integer-based columns like this:
public ActionResult Index()
{
var model1 = this.UnitOfWork.EntityRepository.Get(
includeProperties: "category_id");
// Did that produce an error? If not, try another column:
var model2 = this.UnitOfWork.EntityRepository.Get(
includeProperties: "region_id");
// etc.
// If you get to your original code, then try testing other columns
var model = this.UnitOfWork.EntityRepository.Get();
return View(model);
}
What if the above does not work? There could be an issue with your connection string, as mentioned in this SO answer. This is probably a long-shot, given that your stack trace does not seem to stumble over creating a connection, but it is worth noting in your connection string for MARS there appears to be an extra double quote (though I am sure it is probably just a transcription error.) In any case, if you cannot get any query to work, ensure your connection string looks normal, like the following:
<connectionStrings>
<add name="reuzzeCS"
connectionString=
"server=localhost;database=Reuzze;User Id=root;password=P4ssw0rd"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
What if the above does not work? Check that your version of EntityFramework plays nice with your version of MySQL.
Let's simplify problem. No body can help you unless you want. First of all I must mention that MultipleActiveResultSets=True in your connectionString according to MSDN:
Is a feature that works with SQL Server to allow the execution of multiple batches on a single connection. When MARS is enabled for use with SQL Server, each command object used adds a session to the connection.
So that doesn't work with MySQL!
I think that you need to Specify Port Number in your connectionString like:
<connectionStrings>
<add name="reuzzeCS" connectionString="server=localhost;uid=root;pwd=*****;Persist Security Info=True;database=reuzze;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
Edit :
And, You need to use Connector/Net that is a fully-managed ADO.NET driver for MySQL in this page.It works for most basic scenarios of db interaction. It also has basic Visual Studio integration. According to this page you need connector too.
I hope to be useful. Regards.

How to prevent EF4.1 from creating a DB if it doesn't exist?

I'm using EF4.1 with MVC3 and I need an override to prevent EF from creating a db if it doesn't exist. Instead of creating a new db I would like to catch the error and report that the initial catalog (the database name) is invalid in the connect string.
However, during development I would like to allow for updates for new classes/properties to create according tables/cols in the database.
Is there a best practice or pattern here?
In my application i am completly disable context initializer and handle database mapping and schema manually.
For example :
public class AppDbContext : DbContext
{
public IDbSet<Account> Accounts { get; set; }
public AppDbContext() : base("connection_string")
{
Database.SetInitializer<AppDbContext>(null); // Important! Dont use entity framework initializer !important
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
/* Register custom mapping class */
modelBuilder.Configurations.Add(new AccountMapper());
base.OnModelCreating(modelBuilder);
}
}
And custom mapping :
public class AccountMapper : EntityTypeConfiguration<Account>
{
/// <summary>
/// Employee entity mapper
/// </summary>
public AccountMapper()
{
ToTable("accounts");
HasKey(x => x.Id);
...
}
}
I would suggest looking into the EF database initializer, specifically the IDatabaseInitializer interface.
If you just want it to stop creating the database when it doesn't exist, then just set the Initializer to null. But if you want to log the event or something along those lines then simply create your own IDatabaseInitializer - it's not hard.
You can then set the initializer Application_Start in your global.asax.cs like so:
Database.SetInitializer(new YourCustomInitializer());
As a bonus, here's an example IDatabaseInitializer that I use to run database migrations (using FluentMigrator)... it's extremely handy if I do say so myself!
public class MigrationsDbContextInitializer : IDatabaseInitializer<YourDbContext>
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(MigrationsDbContextInitializer));
public void InitializeDatabase(YourDbContext context)
{
var announcer = new BaseAnnouncer(x => Logger.Info(x));
var runnerContext = new RunnerContext(announcer)
{
Database = "sqlserver2008",
Connection = context.Database.Connection.ConnectionString,
Target = "YourEntitiesNamespace",
PreviewOnly = false,
Task = "migrate"
};
new TaskExecutor(runnerContext).Execute();
}
}

Duplicate entries

I have created a universalrepository that takes the type passed to it and when I create data entry method, the entity is created fine, but when I create a linked entity to it, i get the base entity created again. Any ideas why?
Details..
I have divided a specification into multiple tables to manage stuff...
Now I have got a person entity, an applicant entity...(in reality applicant and person are the same), a contractor entity. A contractor can only be created by an applicant and therefore an applicant will always be created and therefore a person will always be created.
When I go on creating a person, it creates a person fine, but when I create an applicant it creates a person again. Likewise when I create a contractor it creates a person and multiple applicants for some reason.
Here is my LINQ to SQL. If you notice in anyway I can improve this code, I will appreciate that too.
here is the repository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Linq;
namespace ParkingPermit.Models
{
public class UniversalManagerRepository<T> :IRepositoryT<T>
where T:class
{
private Table<T> _table;
private readonly DB _db ;//= new DB();
public UniversalManagerRepository()
{
_db = new DB();
_table = _db.GetTable<T>();
}
#region IRepositoryT<T> Members
public T Create(T create)
{
// _table = new DB().GetTable<T>();
//_db.GetTable(typeof(T)).InsertOnSubmit(create);
_table.InsertOnSubmit(create);
Save();
return create;
}
public void Delete(T delete)
{
throw new NotImplementedException();
}
public T Edit(T edit)
{
throw new NotImplementedException();
}
public T GetItem(int id)
{
throw new NotImplementedException();
}
public T Update(T update)
{
throw new NotImplementedException();
}
public IEnumerable<T> List()
{
//IQueryable i = _db.GetTable(typeof(T)).AsQueryable() ;
return _db.GetTable(typeof(T)) as IEnumerable<T>;
//throw new NotImplementedException();
}
public void Save()
{
//_db.SubmitChanges();
_table.Context.SubmitChanges();
//throw new NotImplementedException();
}
#endregion
}
}
I can post an image of the linq to sql designer if that helps, but I cant see the feature here...
Many thanksalt text http://img509.imageshack.us/img509/2072/linq.jpg
the thing is that when applicant is added and an applicant.Person is assigned from the session(in model binder), it creates a new person, which is actually the original person created in the beginning. How can I avoid that.
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var personType = (Person)controllerContext.HttpContext.Session[PersonSessionKey];
controllerContext.HttpContext.Session[CurrentApplicantSessionKey] = null;
var av = new ApplicantValidator(new ModelStateWrapper(bindingContext.ModelState));
var newApplicant = bindingContext.Model as Applicant;
if (personType == null)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName,
"Cannot Update this Instance directly, please restart the application");
// controllerContext.HttpContext.Session[PersonSessionKey] = personType;
}
else if (newApplicant != null)
{
if (newApplicant.Person != null)
{
if (newApplicant.Person.Equals(personType as Person))
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName,
"A person with these details already exists, please restart the application...");
//return
controllerContext.HttpContext.Session[PersonSessionKey] = null;
personType = null;
}
}
else if (av.Validate(newApplicant))
{
if (newApplicant.Person == null)
{
newApplicant.Person = personType as Person;
newApplicant.PersonId = personType.PersonId;
}
}
}
}
I have resolved this part and apparently its now giving issued with update, can anbody find anything unusual.
Answer to my first problem, was that in Model Binders the entity is being manipulated from sessions and the created back to the service layer.
Apparently it seems that because its all happening outside linq orm framework, this entity needs to be recreated as "From clause ...from ..in db." and then linq correctly recognizes it and does the correct job of insertion.
Can anyone help me with the update/edit..please