ObjectDisposedException EF Error - c#

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.

Related

How to group by List<object> ViewModel in view

I want to group by vitaminlist, but it's not working.
My Model
public class SearchModel
{
public List<tbbesin> besinlist { get; set; }
public List<tbvitamin> vitaminliste { get; set; }
public List<tbmineral> mineralliste { get; set; }
}
My Controller
public ActionResult ara(BesinViewModel model)
{
var listegetir = model.besinler.Split(',');
List<tbbesin> besinliste = new List<tbbesin>();
List<tbmineral> minerallist = new List<tbmineral>();
List<tbvitamin> vitaminlist = new List<tbvitamin>();
SearchModel modelden = new SearchModel();
foreach (var item in listegetir)
{
var ID = int.Parse(item);
var besin = db.tbbesin.FirstOrDefault(x => x.besinid == ID);
var mineral = db.tbmineral.FirstOrDefault(x => x.besinid == ID);
var vitamin = db.tbvitamin.FirstOrDefault(x => x.besinid == ID);
vitaminlist.Add(vitamin);
minerallist.Add(mineral);
besinliste.Add(besin);
}
modelden.besinlist = besinliste.ToList();
modelden.mineralliste = minerallist.ToList();
modelden.vitaminliste = vitaminlist.ToList();
return View(modelden);
}
My View
#model WebApplication1.Models.SearchModel
#foreach (var item22 in Model.vitaminliste.
GroupBy(x => x.vitamindetayid).
Select(x=>x.First()).
ToList())
{
#item22.tbvitamindetay.vitaminad
}
I need to group by in view vitaminlist but its not working.
Why ? Can you help me what is a problem there

How to Convert Anonymous Type to List <dynamic> using Linq to SQL in C#

I'm new to C# and Linq.
Actually, I want to return anonymous types into list. anonymous types is contain of List, String, and DateTime. I tried with the code as below but its giving an error. please help and tell me what I am missing or suggest how can I achieve this.
//Error:
System.InvalidCastException: Specified cast is not valid..
//Edited C# Linq Code
public List<AuditInfo> GetScanAudit(object Id, DateTime? fromTime, DateTime? toTime, string type = null,
string user = null, Pager pager = null)
{
using (var ctx = new PlantDataContext())
{
var query = from audit in ctx.AuditLog
join ent in ctx.Scans on audit.RecordId equals ent.Id.ToString() into audits
from entaudits in audits.DefaultIfEmpty()
where audit.TypeFullName == "ABCD.DB.Model.Scan"
select new
{
audit,
entaudits
};
if (Id != null)
{
query = query.Where(x => x.audit.RecordId == Id.ToString());
}
if (fromTime.HasValue)
{
var tmp = new DateTimeOffset(fromTime.Value.ToUniversalTime());
query = query.Where(x => x.audit.EventDateUTC >= tmp);
}
if (toTime.HasValue)
{
var tmp = new DateTimeOffset(toTime.Value.ToUniversalTime());
query = query.Where(x => x.audit.EventDateUTC <= tmp);
}
if (!string.IsNullOrEmpty(type))
{
var parseEvent = (EventType)Enum.Parse(typeof(EventType), type);
query = query.Where(x => x.audit.EventType == parseEvent);
}
if (!string.IsNullOrEmpty(user))
{
query = query.Where(x => x.audit.UserName == user);
}
if (pager != null)
{
var totalRecords = query.Count();
pager.TotalRecords = totalRecords;
var data = query.Select(x =>
new AuditInfo
{
x.audit.TypeFullName, //Here Error Occurs
x.audit.UserName,//Here Error Occurs
x.audit.EventType,//Here Error Occurs
x.audit.EventDateUTC,//Here Error Occurs
#LogDetails = x.audit.LogDetails.ToList(), //Here Error Occurs
x.entaudits.Name,
#Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.Skip(pager.From)
.Take(pager.PageSize);
try
{
var list1 = data.ToList<AuditInfo>();
}
catch (Exception e)
{
}
var list = data.ToList<AuditInfo>();
pager.RecordCount = list.Count;
return list;
}
else
{
var list = query.Select(x =>
new AuditInfo
{
x.audit.TypeFullName,
x.audit.UserName,
x.audit.EventType,
x.audit.EventDateUTC,
#LogDetails = x.audit.LogDetails.ToList(),
x.entaudits.Name,
#Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.ToList<AuditInfo>();
return list;
}
}
}
When I debug the code totalRecords variable showing count 6, but is showing exception with message Specified cast is not valid at this line var list1 = data.ToList();
You have to cast the anonymous objects to dynamic.
To do this with linq you can use Cast<dynamic> linq method:
var list = query.Select(x =>
new
{
x.audit.TypeFullName,
x.audit.UserName,
x.audit.EventType,
x.audit.EventDateUTC,
#LogDetails = x.audit.LogDetails.ToList(),
x.entaudits.Name,
#Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.AsEnumerable()
.Cast<dynamic>()
.ToList<dynamic>(); \\ here exception occures
return list;
You can use strongly return type for your method like List<ClassName> instead of List<dynamic>
public List<ClassName> GetScanAudit(object Id, DateTime? fromTime, DateTime? toTime, string type = null, string user = null, Pager pager = null)
{
...
}
Then your query will be
var data = query.Select(x =>
new ClassName
{
TypeFullName = x.audit.TypeFullName,
UserName = x.audit.UserName,
EventType = x.audit.EventType,
EventDateUTC = x.audit.EventDateUTC,
LogDetails = x.audit.LogDetails.ToList(),
Name = x.entaudits.Name,
Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.Skip(pager.From)
.Take(pager.PageSize);
var list = data.ToList<ClassName>();
And your strongly type class look like
public class ClassName
{
public string TypeFullName { get; set; }
public string UserName { get; set; }
public string EventType { get; set; }
public DateTime EventDateUTC { get; set; }
public List<LogDetail> LogDetails { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Make sure the datatype of each property should match in your .Select clause in query
Edit:
if (pager != null)
{
var totalRecords = query.Count();
pager.TotalRecords = totalRecords;
var data = query.Select(x =>
new AuditInfo
{
TypeFullName = x.audit.TypeFullName,
UserName = x.audit.UserName,
EventType = x.audit.EventType,
EventDateUTC = x.audit.EventDateUTC,
LogDetails = x.audit.LogDetails.ToList(),
Name = x.entaudits.Name,
Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.Skip(pager.From)
.Take(pager.PageSize);
try
{
var list1 = data.ToList<AuditInfo>();
}
catch (Exception e)
{
}
var list = data.ToList<AuditInfo>();
pager.RecordCount = list.Count;
return list;
}
else
{
var list = query.Select(x =>
new AuditInfo
{
TypeFullName = x.audit.TypeFullName,
UserName = x.audit.UserName,
EventType = x.audit.EventType,
EventDateUTC = x.audit.EventDateUTC,
LogDetails = x.audit.LogDetails.ToList(),
Name = x.entaudits.Name,
Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.ToList<AuditInfo>();
return list;
}

How to OrderBy nested Object value Linq

Object
namespace Example
{
public class ContractorAddValue
{
public Member Member { get; set; }
public List<Addresses> Addresses { get; set; }
public ICommand AddAddress { get; set; }
}
public class Addresses
{
public MemberAddress MemberAddress { get; set; }
public ICommand EditAddress { get; set; }
}
}
Query
public ObservableCollection<ContractorAddValue> GetContractorsOrderByCity()
{
var allContractors = (from c in db.Member where c.IsContrator == true select c).ToList();
//var allContractors2 = db.Member .Include(c => c.MemberAddress).SelectMany(c => c.MemberAddress).OrderBy(c => c.City).Select(c => c.Member ).ToList();
//var allContractors = (from c in db.Member where c.IsContrator == true select c).OrderBy(c => c.MemberAddress.OrderBy(x => x.City)).ToList(); <= dosent work
var listContractorAddValue = new ObservableCollection<ContractorAddValue>();
foreach (var i in allContractors)
{
var adressList = db.MemberAddress.Where(x => x.MemberId == i.MemberId).OrderBy(x => x.City).ToList();
ContractorAddValue contractorAddValue = new ContractorAddValue();
contractorAddValue.Member = i;
contractorAddValue.AddAddress = new BaseCommand(() => ContractorsViewModel.SendAddress(i.MemberId ));
contractorAddValue.Addresses = new List<Addresses>();
foreach (var a in adressList)
{
Addresses memberAdress = new Addresses();
memberAdress.MemberAddress = a;
memberAdress.EditAddress = new BaseCommand(() => ContractorsViewModel.SendEditAddress(a.MemberAddressId , i.MemberId ));
contractorAddValue.Addresses.Add(memberAdress);
}
listContractorAddValue.Add(contractorAddValue);
}
return listContractorAddValue;
}
allContractors2 - the order by works, but I retrieve repeating Members. In this approach I tried to use .Distinct() after Select(c => c.Member) but it doesn't work (the whole query stops working).
My goal is to make an order by MemberAddress.City
Thanks in advance!
I think that this code will work but you need to redefine the Equals method of the ContractorAddValue class.
I added one if statement when you want to add contractorAddValue to the list. First you need to check if your list contains that object. If not you add the object to the list. If yes you need to find that object and merge its addresses list with addresses list from the object you want to add.
public ObservableCollection<ContractorAddValue> GetContractorsOrderByCity()
{
var allContractors = (from c in db.Member where c.IsContrator == true select c).ToList();
//var allContractors2 = db.Member .Include(c => c.MemberAddress).SelectMany(c => c.MemberAddress).OrderBy(c => c.City).Select(c => c.Member ).ToList();
//var allContractors = (from c in db.Member where c.IsContrator == true select c).OrderBy(c => c.MemberAddress.OrderBy(x => x.City)).ToList(); <= dosent work
var listContractorAddValue = new ObservableCollection<ContractorAddValue>();
foreach (var i in allContractors)
{
var adressList = db.MemberAddress.Where(x => x.MemberId == i.MemberId).OrderBy(x => x.City).ToList();
ContractorAddValue contractorAddValue = new ContractorAddValue();
contractorAddValue.Member = i;
contractorAddValue.AddAddress = new BaseCommand(() => ContractorsViewModel.SendAddress(i.MemberId ));
contractorAddValue.Addresses = new List<Addresses>();
foreach (var a in adressList)
{
Addresses memberAdress = new Addresses();
memberAdress.MemberAddress = a;
memberAdress.EditAddress = new BaseCommand(() => ContractorsViewModel.SendEditAddress(a.MemberAddressId , i.MemberId ));
contractorAddValue.Addresses.Add(memberAdress);
}
if(!listContractorAddValue.Contains(contractorAddValue)){
listContractorAddValue.Add(contractorAddValue);
} else {
var contAddValue = listContractorAddValue.First(l => l.Equals( contractorAddValue));
contAddValue.Addresses.AddRange(contractorAddValue.Addresses);
}
}
return listContractorAddValue;
}

Why am I not getting results when performing an intersection?

Users class:
public class User
{
public int ID { get; set; }
public string Email { get; set; }
}
Code:
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users);
foreach (var r in both)
Console.WriteLine(r.Email);
Which returns 0 results.
I know I can accomplish something similar by using join, but I want to use Intersect because A) this is eventually going to work on some DB code and we want to use this function (too long to go into why) and B) I'm just plain curious as to why Intersect isn't working here.
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
.Net provides comparison logic for predefined types. In case of your join query your were joining (comparing) two IDs which were of type Int (predefined types)
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
In case of your intersect query you are trying to compare two user defined custom objects of type User. Hence you need to provide your own custom compare implementation logic.
There are 2 ways to tackle this...
Option 1:
Implement the IEqualityComparer
public class User
{
public int ID { get; set; }
public string Email { get; set; }
}
public class MyEqualityComparer : IEqualityComparer<User>
{
public bool Equals(User x, User y)
{
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.ID.Equals(y.ID) &&
x.Email.Equals(y.Email);
}
public int GetHashCode(User u)
{
return new { u.ID, u.Email }.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users, new MyEqualityComparer());
foreach (var r in both)
Console.WriteLine(r.Email);
}
}
Option 2: Override the Equals and GetHashcode methods in the custom object itself
public class User
{
public int ID { get; set; }
public string Email { get; set; }
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null || GetType() != obj.GetType())
return false;
User x = (User)obj;
return (ID == x.ID) && (Email == x.Email);
}
public override int GetHashCode()
{
return new { ID, Email }.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users);
foreach (var r in both)
Console.WriteLine(r.Email);
}
}
Hope this helps.
This is in response to #sundeep who said "Now regards to your 2nd question... " (I wish you could link to comments) -- I'm just creating a new answer as I don't want to ruin the context of my original question
User class implementing IEqualityComparer
public class User : IEqualityComparer<User>
{
public int ID { get; set; }
public string Email { get; set; }
public bool Equals(User x, User y)
{
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.ID.Equals(y.ID) &&
x.Email.Equals(y.Email);
}
public int GetHashCode(User obj)
{
return new { obj.ID, obj.Email }.GetHashCode();
}
}
Intersection returns no rows:
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc#foo.com"},
new User{ID = 2,Email = "def#foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users);
foreach (var r in both)
Console.WriteLine(r.Email);

EF Code First: The Collection has been modified

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);

Categories