Cannot implicitly convert linq result into viewmodel list - c#

I'm new to MVC and struggling to implement a ViewModel to query multiple tables. Initially my setup worked perfectly but now having reloaded the project I am getting a compilation error as copied below:
Cannot implicitly convert type 'System.Collections.Generic.List<CATEGORY>' to 'System.Collections.Generic.List<TestProject.Models.CATEGORY>'
ViewModel code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestProject.Models
{
public class COMPCATEGORY
{
public List<COMP> Comp { get; set; }
public List<CATEGORY> Category { get; set; }
}
}
Controller Code:
namespace TestProject.Controllers
{
public class COMPsController : Controller
{
private mattbeaneyEntities1 db = new mattbeaneyEntities1();
// GET: COMPs
public ActionResult Index()
{
COMPCATEGORY viewModel = new COMPCATEGORY();
viewModel.Category = db.CATEGORies.ToList();
viewModel.Comp = db.COMPs.ToList();
return View(viewModel);
}
DB Context code:
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class mattbeaneyEntities1 : DbContext
{
public mattbeaneyEntities1()
: base("name=mattbeaneyEntities1")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<CATEGORY> CATEGORies { get; set; }
public virtual DbSet<COMP> COMPs { get; set; }
}

As the error suggests it is having trouble with two types by the same name, when we were only expecting one. The namespace is our clue here:
Cannot implicitly convert type 'System.Collections.Generic.List<CATEGORY>' to 'System.Collections.Generic.List<TestProject.Models.CATEGORY>'
Usually there are a couple of things I like to check in this case:
Firstly: are there two classes that share the same name and belong to different namespaces? It's quite easy to do as your project grows!
Secondary: has the main project namespace changed? Sometimes due to a bit of refactoring we change the project name and then end up with two .dll files in the bin folder, which hold duplicate of all our classes - delete the old one!

Related

Using a Database Context in multiple projects within the same solution

I'm currently working on a program that is being used to generate PDF's and documents. There are two different use cases, one being an automated process and the second being a manual process where data can be edited via a front-end app.
The solution has 2 Projects in it, the first for the automated part, and the second for the manual part.
However, since the two processes make use of the same data and templates, I've split the solution into two parts, this will allow me to set it up in a way in which I only need to maintain models/templates once.
My database context looks like this:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RefundTracker.Models
{
public class DatabaseContext : DbContext
{
public DatabaseContext()
:base("Prod")
{
}
public DbSet<Referral> Referrals { set; get; }
public DbSet<ReferralAppointment> ReferralAppointments { set; get; }
public DbSet<ReferralPayment> ReferralPayments { set; get; }
public DbSet<BankDetails> BankDetails { set; get; }
public DbSet<ReferralAppointment_History> ReferralAppointment_History { set; get; }
public DbSet<ReferralPayment_History> ReferralPayment_History { set ; get; }
public DbSet<IsInUse> IsInUse { set; get; }
}
}
In terms of projects, I have a project called "RefundTracker" and another called "MailMergeTPA".
The context provided above, together with all of the models, are located in the "RefundTracker" project.
I would like to make use of these models and context in the "MailMargeTPA" project as well.
I referenced the "RefundTracker" in "MailMergeTPA" project, however, no results when using the context here. (When I access a function that get a list of names for instance, I get the full list in "RefundTracker", however, I get no results when I use the same function in "MailMergeTPA".
Code Example:
public BankDetails GetBankDetails(Referral record)
{
string bName = record.bankName.Trim();
try
{
BankDetails bankDetails= new BankDetails();
List<BankDetails> bankDetails = new List<BankDetails>();
using (DatabaseContext db = new DatabaseContext())
{
bankDetails = db.BankDetails.SingleOrDefault(a => a.BankName == bName);
}
return bankDetails;
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
return null;
}
I would like to make use of this exact function in both projects.
Could you kindly help me with some advice? (Please go easy on me in the comments, I'm still fairly new to EF)
I've tried referencing the project, no result.
I've read up on interfaces, however, I'm unsure as to how I would incorporate this.

C# EF Required Attribute not recognized

I am creating an app that uses a database (SQLite). I am using entity framework and ADO.NET to interact with it.
I have a seprate Models project in my app that contains all of my Database models.
Now I want to mark some of my class properties as required to reflect the "NOT NULL" option in my database. But if I add the [Required] Attribute from DataAnnotations namespace I get a compiler error saying it cannot be resolved.
Here is how my class looks like :
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ReflowModels
{
public class Tag
{
public Tag()
{
this.Options = new HashSet<Option>();
}
public int Id { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Option> Options { get; set; }
}
}
I have also added a reference to EntityFramework.dll in my project.
you need to add this to your using block
using System.ComponentModel.DataAnnotations.Schema;
you need to add this to your using block
using System.ComponentModel.DataAnnotations;
In case it still doesn't work, maybe you should add it to your References

what 's the use of creating a metadata class and a partial class for the model class c#

I just joined a new company and my manager just joined too, and he wants to change the way we program. basically do what he does. I'm wondering what's the difference, pros, cons, limitation and problems if there'll be any..here's the sample
namespace Models //this is the model part of from edmx
{
using System;
using System.Collections.Generic;
public partial class MyModelClass
{
public int ID { get; set; }
public Nullable<System.DateTime> PostDate { get; set; }
public string MyContent { get; set; }
}
}
this is the metadata:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Models
{
public class MyModelMetaData
{
//he wants all data annotation here
public int ID { get; set; }
public Nullable<System.DateTime> PostDate { get; set; }
public string MyContent { get; set; }
}
}
this is the partial:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace Models
{
[MetadataType(typeof(MyModelMetaData))]
public partial class MyModelClass or MyModelClassPartial
{
//He wants the programming algorithm to go here
}
}
Please enlightened me. and he wants to create different metadata and partial classes per model class..way too many files involved.
thank you..i need an answer as to why..if you think his method is good..I will do this..but if you think this will cause problem in the future and more coding will be involve..i need to know
The first class you show, the entity classes, are generated from the database every time you save the EDMX (or when you execute the T4 Template).
This causes the file containing public partial class MyClass under the EDMX to be regenerated. So you cannot alter it, because the next time someone refreshes a table or adds one, your changes are gone.
That's why entity classes are generated as a partial: so you can create another partial to the same class to do your modifications in.
However, if you want to annotate your entity's properties with metadata, you cannot redefine the same property in the other partial class: the same name can only be used by one member of a type. So you can't do this:
// Entity class
public partial class FooEntity
{
public string Name { get; set;}
}
// User-created partial class
public partial class FooEntity
{
[Required]
public string Name { get; set;}
}
Because that code expresses you want two properties named Name in the FooEntity class, which is not valid.
So you'll have to come up with another way to add metadata to the type. Enter the [MetadataType] attribute. This works by creating a new class with the same properties as the class to be annotated. Here, using reflection, the metadata is resolved based on member name.
So when you create a metadata class for the above annotation:
public class FooEntityMetadata
{
[Required]
public string Name { get; set;}
}
You can apply it to the user-created partial:
// User-created partial class
[MetadataType(typeof(FooEntityMetadata))]
public partial class FooEntity
{
}
And also, in the latter partial, you can add members that add functionality to the entity model. New ([NotMapped]) properties and new methods for example.
I think the one use could be to not pollute the main class.
For example if you have a lot of attribute for validation (using dataannotation) and you don't want to have them in the main class you could use the MetadataTypeAttribute for that.
Another use could be if your class is auto-generated and you need to add some decoration (more attributes) to your properties without changing the autogenerated code.

Does Not Implement Interface in sportsstore asp.net mvc 5

I'm following on asp.net mvc 5 book by apress and I've got stuck at one point with this error:
"SportsStore.Domain.Concrete.EFProductRepository' does not implement
interface member
'SportsStore.Domain.Abstract.IProductRepository.Products.set"
This is what I have in EFProductRepository:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Concrete
{
public class EFProductRepository : IProductRepository
{
public EFDbContext context = new EFDbContext();
public IEnumerable<Product> Products
{
get { return context.Products; }
}
}
}
And in IProductRepository I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract
{
public interface IProductRepository
{
IEnumerable<Product> Products { get; set; }
}
}
Why am I getting the error in EFProductRepository.cs class?
Because you're not implementing a setter for the property. Look at the interface's definition:
IEnumerable<Product> Products { get; set; }
And look at your implementation:
public IEnumerable<Product> Products
{
get { return context.Products; }
}
You need to either implement a set in the property, or remove set from the interface definition. Given the implementation of the property, I'm guessing the latter is more appropriate.
If it helps, since it looks like you're building a repository for Entity Framework objects, here's what one of mine generally looks like:
public interface ProductRepository
{
IQueryable<Product> Products { get; }
void Add(Product model);
void Remove(Product model);
}
and the implementation:
public class ProductRepositoryImplementation : ProductRepository
{
private DbSet<Product> _products;
public IQueryable<Product> Products
{
get { return _products; }
}
public ProductRepositoryImplementation(DbSet<Product> products)
{
_products = products;
}
public void Add(Product model)
{
_products.Add(model);
}
public void Remove(Product model)
{
_products.Remove(model);
}
}
Generally this is housed within a unit of work object, which extends DbContext and handles committing the changes to its repositories. (That's also what passes the DbSet<> to the constructor for the repositories.) I actually just blogged about this setup today.
The error seems pretty clear - you need to either add a set accessor to your property or remove it from the interface. In your case it probably makes more sense to remove it from the interface:
namespace SportsStore.Domain.Abstract
{
public interface IProductRepository
{
IEnumerable<Product> Products { get; /*set;*/ }
}
}
Adding entities to a repository via a set accessor doesn't seem proper - usually a repository has a Save or Update method that works on one entity at a time.

Type information not showing in LINQ expression in Entity Framework 2012

I am new to Entity Framework but trying get my hands into it. After going thru many blogs I have started working on implementing it in my project but I have the following issue.
I have VS 2012 and working on a project of version 4.0.
I added DataModel.edmx file in my project which created 4 more files
DataModel.Context.tt , DataModel.Designer.cs , DataModel.edmx.diagram , DataModel.tt
Looks fine till this point. But when I try to access the table information in my Linq query. Intellisense is not showing up anything.
var context = new DataModelEntities();
var invoice = from c in context.Invoice select c.{//NOTHING SHOWING HERE};
DataModelEntities class (DataModel.Context.cs) looks like
namespace MySpace.Objects.DataModel
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class DataModelEntities : DbContext
{
public DataModelEntities()
: base("name=KKEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Invoice> Invoice { get; set; }
public DbSet<InvoiceContracts> InvoiceContracts { get; set; }
}
}
The Invoice class looks like:
//-----------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//--------
namespace MySpace.Objects.DataModel
{
using System;
using System.Collections.Generic;
public partial class Invoice
{
public int ID { get; set; }
public int POID { get; set; }
}
}
Please let me know if I am missing anything.
Thank you...
rename
public DbSet<Invoice> Invoice { get; set; }
to
public DbSet<Invoice> Invoices { get; set; }
then try
var invoice = c in context.Invoices.Select( c=>c.HERE)
This is only a query specification (of type IQueryable<Invoice>):
var invoiceQuery = from c in context.Invoice select c;
(invoiceQuery is a better name than invoice here.) It is not the result of an executed query and no query has been sent to the database a this point. To get the result of the query you must apply an operator that causes the query to execute, for example ToList() or FirstOrDefault(), etc.:
var invoices = invoiceQuery.ToList();
This is of type List<Invoice>.

Categories