EF Code First: The Collection has been modified - c#

Getting this error when try to add an item to my repositories/context:
Collection has been modified. Possibly the inventory operation is not performed.
What I'm trying to do
Campaign c = Campaignrepository.FindById(id);
if (c.LandingPage == null)
{
c.LandingPage = new Page() { Campaign = c, CampaignID = c.Campaignid };
PageRepository.Add(c.LandingPage);
}
if (c.RedeemPage == null)
{
c.RedeemPage = new RedeemPage() { Campaign = c, CampaignID = c.Campaignid };
PageRepository.Add(c.RedeemPage);
}
The Repository Add method:
public void Add(Page p)
{
pages.Add(p);
context.SaveChanges();
}
Update: still same error.
After applying the suggestions:
public ActionResult Edit(int id)
{
Campaign c = Campaignrepository.FindById(id);
Campaign newreferenceC = Campaignrepository.FindById(id);
if (c.LandingPage == null)
{
c.LandingPage = new Page() { Campaign = newreferenceC, CampaignID = newreferenceC.Campaignid };
PageRepository.Add(c.LandingPage);
}
if (c.RedeemPage == null)
{
c.RedeemPage = new RedeemPage() { Campaign = newreferenceC, CampaignID = newreferenceC.Campaignid };
PageRepository.Add(c.RedeemPage);
}
return View("Edit", Campaignrepository.FindById(id));
}

Manged to fix it with:
Page landingPage = new Page(c);
RedeemPage redeemPage = new RedeemPage(c);
PageRepository.Add(landingPage);
PageRepository.Add(redeemPage);
c.LandingPage = landingPage;
c.RedeemPage = redeemPage;
Campaignrepository.Update(c);

Related

How to send model bind to devexpress gridview back to controller during callback?

I would like to pass the model bind to devexpress gridview back to controller during callback but failed.
Models
public class UploadExcelError
{
public int rowNumber { get; set; }
public string errorMessage { get; set; }
}
public class UploadViewModel
{
public List<UploadExcelError> UploadExcelErrors { get; set; }
public UploadFile UploadFile { get; set; }
}
UploadErrorPartial.cshtml
#using ControlTower2.Models
#model ControlTower2.Models.UploadViewModel
#if (Model != null)
{
if (Model.UploadExcelErrors != null)
{
#Html.DevExpress().GridView(
settings =>
{
settings.Name = "gridViewExcelError";
settings.CallbackRouteValues = new { Controller = "PurchaseOrder", Action = "FilteringError", xyz = Model };
settings.SettingsBehavior.AllowSort = false;
settings.SettingsPager.Mode = GridViewPagerMode.ShowAllRecords;
settings.Columns.Add(column => { column.FieldName = "rowNumber"; column.Caption = "Excel Row#"; });
settings.Columns.Add(column => { column.FieldName = "errorMessage"; column.Caption = "Error Message"; });
settings.Settings.ShowHeaderFilterButton = true;
var headerFilterMode = GridHeaderFilterMode.List;
foreach (GridViewDataColumn column in settings.Columns)
column.SettingsHeaderFilter.Mode = headerFilterMode;
}
).Bind(Model.UploadExcelErrors).GetHtml()
}
}
Controller
public ActionResult FilteringError(UploadViewModel xyz)
{
return PartialView("UploadErrorPartial", xyz);
}
xyz is null in code above.
I also tried:
settings.CallbackRouteValues = new { Controller = "PurchaseOrder", Action = "FilteringError", xyz = Model.UploadExcelErrors };
public ActionResult FilteringError(List<UploadExcelError> xyz)
{
UploadViewModel uploadViewModel = new UploadViewModel();
uploadViewModel.UploadExcelErrors = xyz;
return PartialView("UploadErrorPartial", uploadViewModel);
}
xyz is not null but count is zero. But It has show 4 rows of data on UploadErrorPartial.cshtml
I tried ViewData too:
UPDATE - ViewData only transfers data from controller to view, that's why this won't work.
if (Model.UploadExcelErrors != null)
{
ViewData["xyz"] = Model;
#Html.DevExpress().GridView(
settings =>
{
settings.Name = "gridViewExcelError";
settings.CallbackRouteValues = new { Controller = "PurchaseOrder", Action = "FilteringError" };
settings.SettingsBehavior.AllowSort = false;
settings.SettingsPager.Mode = GridViewPagerMode.ShowAllRecords;
settings.Columns.Add(column => { column.FieldName = "rowNumber"; column.Caption = "Excel Row#"; });
settings.Columns.Add(column => { column.FieldName = "errorMessage"; column.Caption = "Error Message"; });
settings.Settings.ShowHeaderFilterButton = true;
var headerFilterMode = GridHeaderFilterMode.List;
foreach (GridViewDataColumn column in settings.Columns)
column.SettingsHeaderFilter.Mode = headerFilterMode;
}
).Bind(Model.UploadExcelErrors).GetHtml()
}
public ActionResult FilteringError()
{
UploadViewModel uploadViewModel = (UploadViewModel)ViewData["xyz"];
return PartialView("UploadErrorPartial", uploadViewModel);
}
uploadViewModel get null from (UploadViewModel)ViewData["xyz"].
I use session to store Model.UploadExcelErrors and it solves my problem.

ObjectDisposedException EF Error

I´m having a problem because always I press the Action Button I got the this Exception.
This part is giving me a error
public void InserirComCopia(TabelaPreco tabPrec, string copiarDe)
{
var lista = new List<PrecoProduto>();
var tb = InserirTabelaVazia(tabPrec);
var rep = new PrecoRepositorio();
lista = rep.ObterPrecoPorTabela(Int32.Parse(copiarDe));
var ls = new List<PrecoProduto>();
using (var context = new indigo.DataModel.IndigoContext())
{
foreach (var item in lista)
{
var p = new PrecoProduto()
{
preco = item.preco,
TabPreco = tb,
TabPrecoId = tb.Id,
Produto = item.Produto,
ProdutoId = item.ProdutoId
};
ls.Add(p);
}
context.PrecoProduto.AddRange(ls);
context.SaveChanges();
}
}
And this is all my controller:
public TabelaPreco ObterTablePrecoPorID(int Id, List<TabelaPreco> tabelaPreco)
{
return tabelaPreco.Where(t => t.Id == Id)
.FirstOrDefault();
}
public List<TabelaPreco> ObterTodasAsTabelas()
{
List<TabelaPreco> model = new List<TabelaPreco>();
using (var context = new indigo.DataModel.IndigoContext())
{
model = context.TabelaPreco.ToList();
}
return model;
}
public List<TabelaPreco> Buscar(string busca)
{
List<TabelaPreco> model = new List<TabelaPreco>();
using (var context = new indigo.DataModel.IndigoContext())
{
model = context.TabelaPreco.Where(tb => tb.Desc.Contains(busca)).ToList();
}
return model;
}
public TabelaPreco InserirTabelaVazia(TabelaPreco tab)
{
using (var context = new indigo.DataModel.IndigoContext())
{
context.TabelaPreco.Add(tab);
context.SaveChanges();
return tab;
}
}
public void Deletar(int id)
{
var tabela = new TabelaPreco();
using (var context = new indigo.DataModel.IndigoContext())
{
tabela = context.TabelaPreco.Where(tb => tb.Id == id)
.FirstOrDefault();
context.TabelaPreco.Remove(tabela);
context.SaveChanges();
}
}
public void InserirComCopia(TabelaPreco tabPrec, string copiarDe)
{
var lista = new List<PrecoProduto>();
var tb = InserirTabelaVazia(tabPrec);
var rep = new PrecoRepositorio();
lista = rep.ObterPrecoPorTabela(Int32.Parse(copiarDe));
var ls = new List<PrecoProduto>();
using (var context = new indigo.DataModel.IndigoContext())
{
foreach (var item in lista)
{
var p = new PrecoProduto()
{
preco = item.preco,
TabPreco = tb,
TabPrecoId = tb.Id,
Produto = item.Produto,
ProdutoId = item.ProdutoId
};
ls.Add(p);
}
context.PrecoProduto.AddRange(ls);
context.SaveChanges();
}
}
public TabProdListModel PegarProdutosDaTabela(int id)
{
using (var context = new indigo.DataModel.IndigoContext())
{
var modelTab = context.TabelaPreco.Where(tb => tb.Id == id).First();
var modelProd = context.Produto.ToList();
var model = context.TabelaPreco
.Where(t => t.Id == id)
.Join(
context.PrecoProduto,
t => t.Id,
x => x.TabPrecoId,
(t, x) => new { t, x }
)
.Join(
context.Produto,
p => p.x.ProdutoId,
y => y.Id,
(p, y) => new ListProduto
{
produtoId = y.Id,
produto = y.Nome,
precoProduto = p.x.preco,
Cor = y.Cor,
Tamanho = y.Tamanho
}
)
.ToList();
var ls = new TabProdListModel()
{
tabela = modelTab,
Produtos = modelProd,
TdProdutos = model
};
var prod = ls.Produtos.ToList();
if (modelProd.Count() != 0)
foreach (var item in ls.Produtos)
{
foreach (var td in ls.TdProdutos)
{
if (item.Id == td.produtoId)
{
prod.Remove(item);
break;
}
}
}
ls.Produtos = prod;
return ls;
}
}
public void AdicionarProdTab(int Produto, double Valor, int Tabela)
{
using(var context = new indigo.DataModel.IndigoContext())
{
var produto = context.Produto.Where(p => p.Id == Produto).FirstOrDefault();
var tabela = context.TabelaPreco.Where(tp => tp.Id == Tabela).FirstOrDefault();
var precoProduto = new PrecoProduto()
{
preco = Valor,
Produto = produto,
TabPreco = tabela
};
context.PrecoProduto.Add(precoProduto);
context.SaveChanges();
}
}
public void EditarProdutoTabela(int ProdutoId, double valor, int tabela)
{
using (var context = new indigo.DataModel.IndigoContext())
{
var precoProduto = context.PrecoProduto.Where(x => x.ProdutoId == ProdutoId && x.TabPrecoId == tabela).FirstOrDefault();
precoProduto.preco = valor;
context.PrecoProduto.Attach(precoProduto);
var Entry = context.Entry(precoProduto);
Entry.Property(e => e.preco).IsModified = true;
context.SaveChanges();
}
}
public void Remover(int id)
{
}
Please help me!
PS: Sorry for my bad english, I´m a Brazilian code student
UPDATE:
My repository:
public List<PrecoProduto> ObterPrecoPorTabela(int copiarDe)
{
var Precos = new List<PrecoProduto>();
using (var context = new indigo.DataModel.IndigoContext())
{
Precos = context.PrecoProduto.Where(pp => pp.TabPrecoId == copiarDe).ToList();
}
return Precos;
}
On this line: TabPreco = tb, and then here Produto = item.Produto, I'm not positive you can do. You are taking an object that's correctly connected to your database context and trying to attach it to something that's no longer attached. Perhaps try removing those lines to see if it helps? I can't imagine why you'd need to both set those and set the IDs. You should only need to do one or the other.

Multi select list box asp mvc

I'm working on an mvc .net web application and I'm using Entity Framework.
In my model, I have an entity called "utisateur" (user) and every user has one or more users that supervise him. What I want to do is generate a multi select list box that contains the list of all users inorder to select the new users' supervisors.
I tried to to that but i got this error :
Object reference not set to an instance of an object.
Here is my model class :
public class util
{
public util()
{
user = new utilisateur();
listesups = Getutilisateurs(null);
}
public utilisateur user { get; set; }
public int[] selectedusers;
public MultiSelectList listesups { get; set; }
public MultiSelectList Getutilisateurs(int[] selectedValues)
{
var db = new BDGestionEntities();
List<utilisateur> utilisateurs = db.utilisateurs.ToList();
return new MultiSelectList(utilisateurs, "id", "login", selectedValues);
}
}
And here is the part of the view that contains the list box :
#Html.ListBoxFor(model => model.selectedusers, Model.listesups)
Here is the controller
public ActionResult Create2()
{
return View();
}
[HttpPost]
public ActionResult Create2(util model)
{
utilisateur u = new utilisateur();
if (model.selectedusers != null)
{
foreach (var selecteduse in model.selectedusers)
{
int selecteduseId = selecteduse;
utilisateur utilisateur = db.utilisateurs.Where(c => c.id == selecteduseId).FirstOrDefault();
u.superieur.Add(utilisateur);
}
}
u.nom = model.user.nom;
u.prenom = model.user.prenom;
u.solde_conge = model.user.solde_conge;
u.email = model.user.email;
u.login = model.user.login;
u.pwd = model.user.pwd;
role role = new role();
//role.nom_role = model.nom_role;
role = db.roles.Where(c => c.nom_role == model.nom_role).FirstOrDefault();
u.role = role;
db.utilisateurs.AddObject(u);
db.SaveChanges();
ViewBag.id_role = new SelectList(db.roles, "id", "nom_role", model.user.id_role);
return RedirectToAction("index");
}
And here is the error message
Server Error in '/' Application.
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 44: <tr><td><label><b>Role : </b></label></td><td>#Html.DropDownListFor(model => model.nom_role, values)</td></tr>
Line 45: <tr>
Line 46: <td><label><b>Liste des supérieurs : </b></label></td><td>#Html.ListBoxFor(model => model.selectedusers, Model.listesups)</td></tr>
Line 47: </table>
Line 48: <p>
I solved this by editing my Create2() method like this :
public ActionResult Create2()
{
string login = User.Identity.Name;
utilisateur ut = new utilisateur();
var q = from j in db.utilisateurs where j.login == login select j;
foreach (var i in q)
ut = i;
if ((ut.role.nom_role == "Stagiaire") || (ut.role.nom_role == "Developpeur"))
return Redirect("~/Erreur");
util u = new util();
u.listesups = new MultiSelectList (db.utilisateurs, "id", "login");
return View(u);
}
[HttpPost]
public ActionResult Create2(FormCollection collection, util model)
{
var sups = collection["selectedusers"];
string login = User.Identity.Name;
utilisateur u = new utilisateur();
List<int> nums = new List<int>();
var q = from j in db.utilisateurs where j.login == login select j;
utilisateur courant = new utilisateur();
try
{
foreach (var i in q)
{
courant = i;
}
foreach (var s in sups.Split(','))
{
nums.Add(int.Parse(s));
}
}
catch(Exception ex)
{
Logger.Warning(ex.Message, "aucun superieur selectionné");
}
try
{
foreach (var selecteduse in nums)
{
utilisateur utilisateur = db.utilisateurs.Where(c => c.id == (int)selecteduse).FirstOrDefault();
u.superieur.Add(utilisateur);
}
}
catch(Exception ex)
{
Logger.Error(ex.Message, "Erreur ajout supérieurs");
}
//}
if ((model.user.nom != null) && (model.user.prenom != null) && (model.user.login != null) && (model.user.email != null))
{
u.nom = model.user.nom;
u.prenom = model.user.prenom;
u.solde_conge = model.user.solde_conge;
u.email = model.user.email;
u.login = model.user.login;
u.pwd = model.user.pwd;
role role = new role();
role = db.roles.Where(c => c.nom_role == model.nom_role).FirstOrDefault();
u.role = role;
try
{
db.utilisateurs.AddObject(u);
db.SaveChanges();
}
catch (Exception ex)
{
Logger.Error(ex.Message, "");
}
ViewBag.id_role = new SelectList(db.roles, "id", "nom_role", model.user.id_role);
return RedirectToAction("index");
}

How to search for "Not Contains" condition on collection of objects in RavenDB

I'm new to the RavenDB and I am struck with a condition here.Basically this is what I want to achive I have a list of the employees in the RavenDB and I need to fetch employees who are not of the type "Contract".I tried to use basic linq query but I am unable to resolve the issue as I am geting exceptions like "Method Not Supported" and "Cannot understand how to translate ... etc".
This is what I have tried untill now.
class Program
{
static void Main(string[] args)
{
using (var documentStore = new DocumentStore() { ConnectionStringName = "RavenDBConnectionString" })
{
documentStore.Initialize();
/* using (var session = documentStore.OpenSession())
{
session.Store(new User { Id = 1, Roles = new List<Role> { new Role { Type = UserType.Contract }, new Role { Type = UserType.Developer } } });
session.Store(new User { Id = 2, Roles = new List<Role> { new Role { Type = UserType.Permanent }, new Role { Type = UserType.Developer } } });
session.Store(new User { Id = 3, Roles = new List<Role> { new Role { Type = UserType.SeniorDeveloper }, new Role { Type = UserType.Manager } } });
session.Store(new User { Id = 4, Roles = new List<Role> { new Role { Type = UserType.Contract }, new Role { Type = UserType.SeniorDeveloper } } });
session.Store(new User { Id = 5, Roles = new List<Role> { new Role { Type = UserType.Permanent }, new Role { Type = UserType.Manager } } });
session.Store(new User { Id = 6, Roles = new List<Role> { new Role { Type = UserType.Contract }, new Role { Type = UserType.Developer } } });
session.SaveChanges();
}*/
using (var session = documentStore.OpenSession())
{
//var nonContractEmployees = session.Query<User>().Where(x => !x.Roles.Exists(y => y.Type == UserType.Contract)).ToList();
var nonContractEmployees = session.Query<User>().Where(x => x.Roles.Count(y => y.Type == UserType.Contract) == 0).ToList();
// var nonContractEmployees = session.Query<User>().Where(x => !x.Roles.Contains(x.Roles.FirstOrDefault(y => y.Type == UserType.Contract))).ToList();
//var nonContractEmployees = session.Query<User>().Where(x => x.Roles.FirstOrDefault(y => y.Type == UserType.Contract) == null).ToList();
}
}
}
}
public class User
{
public int Id { get; set; }
public List<Role> Roles { get; set; }
}
public class Role
{
public UserType Type { get; set; }
}
public enum UserType
{
Manager,
Permanent,
Contract,
Developer,
SeniorDeveloper
}
I would really appretiate it if someone can help me in resolving this issue.
Thanks,
Kapil
Edit 1
var nonContractEmployees = session.Query<User>()
.Where(x => !x.Roles.In(new [] {new Role { Type = UserType.Contract}))
.ToList();
Edit 2
This works but isn't efficient.
using (var session = documentStore.OpenSession())
{
var nonContractEmployees = session.Query<User>()
.ToList()
.Where(x => x.Roles.Contains(
new Role {Type = UserType.Contract},
new RoleComparer()));
}
public class RoleComparer : IEqualityComparer<Role>
{
public bool Equals(Role x, Role y)
{
return
x == null && y == null ||
x != null &&
y != null &&
x.Type == y.Type;
}
public int GetHashCode(Role obj)
{
return
obj == null
? 0
: obj.Type.GetHashCode();
}
}
Try:
var nonContractEmployees = session.Query<User>()
.Where(x => !x.Roles.Any(y => y.Type == UserType.Contract))
.ToList();
I've updated my Query with what it should be. (currently failing)
And I've submitted a failing test to Ayende to your query on the Google Group.
https://groups.google.com/forum/?fromgroups#!topic/ravendb/LpSo3VdkavI

Collection not populated with Fluent NHibernate

I am having an odd error when using Fluent NHibernate. I have an entity object called Module that is my "aggregate root" if you will. I created and tested my mappings for the Module class and the various related classes and tried creating a Module with all of its fields filled out and saving it. This worked correctly.
My problem is when I try to retrieve the objects from the database. The Module object comes back just fine, however any of the collections it contains are all empty even though I see the objects in the database tables!! I could really use a hand on this one, I hope somone can help!
edit: added the code for BuildDeriveModule below.
Here is my test:
var dei1 = BuildDeriveModule();
var sessionSource = Injector.Resolve<ISessionSource>();
using (var session = sessionSource.CreateSession())
{
using (var transaction = session.BeginTransaction())
{
session.Save(dei1);
transaction.Commit();
}
}
Module item = null;
using (var session = sessionSource.CreateSession())
{
item = session
.CreateCriteria(typeof(Module))
.Add(Restrictions.Eq("ModuleId", dei1.ModuleId))
.UniqueResult<Module>();
Assert.Equal<Module>(dei1, item);
Assert.Equal<int>(4, item.Variables.Count);
}
My Module class looks like this: (Note: Entity comes from FluentNHibernate.Data.Entity)
public class Module : Entity, IEntity
{
public Module()
{
Variables = new HashedSet<ModuleVariable>();
}
public virtual string ModuleId
{
get;
set;
}
public virtual ISet<ModuleVariable> Variables
{
get;
set;
}
public virtual Variable StratumVariable
{
get;
set;
}
public virtual Stratum DefaultStratum
{
get;
set;
}
public virtual ISet<Stratum> OptionalStrata
{
get;
set;
}
public virtual DateTime LastUpdated
{
get;
set;
}
#region Override Methods
public override string ToString()
{
return this.ModuleId;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
var other = obj as Module;
if (other == null) return false;
if (other.ModuleId != this.ModuleId) return false;
return true;
}
public override int GetHashCode()
{
return ModuleId.GetHashCode();
}
#endregion
}
And my Mapping looks like this:
public class ModuleMap : ClassMap<Module>
{
public ModuleMap()
{
Id(x => x.Id);
Version(x => x.LastUpdated);
Map(x => x.ModuleId)
.Unique()
.Not.Nullable();
HasMany<ModuleVariable>(x => x.Variables)
.Inverse()
.Cascade.SaveUpdate();
References<Variable>(x => x.StratumVariable)
.Not.Nullable()
.Cascade.SaveUpdate();
References<Stratum>(x => x.DefaultStratum)
.Not.Nullable()
.Cascade.SaveUpdate();
HasMany<Stratum>(x => x.OptionalStrata)
.Inverse()
.Cascade.SaveUpdate();
}
}
BuildDeriveModule's code:
private Module BuildDeriveModule()
{
var pp01 = new Relation
{
RelationId = "PP01"
};
var hh01 = new Relation
{
RelationId = "HH01"
};
var stdei1 = new Variable
{
VariableId = "STDEI1",
Relation = pp01
};
var frameId = new Variable
{
VariableId = "FRAME_ID",
Relation = pp01
};
var persno = new Variable
{
VariableId = "PERSNO",
Relation = pp01
};
var hp = new Driver
{
Name = "HP",
Phase = 1
};
hp.KeyVariables.Add(frameId);
hp.KeyVariables.Add(persno);
var r2p1 = new Variable
{
VariableId = "R2P1",
Relation = pp01
};
var age = new Variable
{
VariableId = "AGE",
Relation = pp01
};
var marst = new Variable
{
VariableId = "MARST",
Relation = pp01
};
var doctp = new Variable
{
VariableId = "DOCTP",
Relation = hh01
};
pp01.AddVariable(stdei1);
pp01.AddVariable(r2p1);
pp01.AddVariable(age);
pp01.AddVariable(marst);
hh01.AddVariable(doctp);
var defaultStratum = new Stratum
{
Number = -1,
Driver = hp
};
var dei1 = new Module
{
ModuleId = "DEI1",
StratumVariable = stdei1,
DefaultStratum = defaultStratum
};
var mv_r2p1 = new ModuleVariable
{
ModuleId = dei1,
VariableId = "R2P1",
UploadId = r2p1,
DownloadId = r2p1,
HasSubunits = true
};
var mv_age = new ModuleVariable
{
ModuleId = dei1,
VariableId = "AGE",
UploadId = age,
DownloadId = age,
HasSubunits = true
};
var mv_marst = new ModuleVariable
{
ModuleId = dei1,
VariableId = "MARST",
UploadId = marst,
DownloadId = marst,
HasSubunits = true
};
var mv_doctp = new ModuleVariable
{
ModuleId = dei1,
VariableId = "DOCTP",
UploadId = doctp,
DownloadId = doctp,
HasSubunits = false
};
dei1.AddVariable(mv_r2p1);
dei1.AddVariable(mv_age);
dei1.AddVariable(mv_marst);
dei1.AddVariable(mv_doctp);
return dei1;
}
OK, I think I got it to work. I removed the .Inverse() from thins line
HasMany<ModuleVariable>(x => x.Variables)
.Inverse()
.Cascade.SaveUpdate();
in ModuleMap and the unit test worked. I'm not quite sure why though, so if anyone can point out that out it would be appreciated.

Categories