I have something like this
public class AViewModel
{
public decimal number { get; set; }
public List<BViewModel> BVM { get; set; }
}
public class BViewModel
{
public string someString{ get; set; }
}
public class SomeObject
{
public decimal number { get; set; }
public List<OtherObjects> BVM { get; set; }
}
public class OtherObjects {
public string someString{ get; set; }
}
Mapper.CreateMap<SomeObject,AViewModel>();
When I have this I get
Trying to map OtherObjects to BViewModel
Using mapping configuration for SomeObject to AViewModel
Destination property: BVM
Missing type map configuration or unsupported mapping.
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
How can I help it figure out how to map it properly?
I believe Automapper needs to know how to convert OtherObject to BViewModel. Try adding a mapping for that too.
You need to specify a typeconverter between OtherObject and BViewModel by specifying a custom type converter
Here's what the converter would look like:
public class OtherToBViewTypeConverter : ITypeConverter<OtherObjects, BViewModel>
{
public BViewModel Convert(ResolutionContext context)
{
if (context.IsSourceValueNull) return null;
var otherObjects = context.SourceValue as OtherObjects;
return new BViewModel { someString = otherObjects.someString; }
}
}
And then the map would be called like this:
Mapper.CreateMap<SomeObject,AViewModel>().ConvertUsing<OtherToBViewTypeConverter>();
Related
i am using Database first method. EDMX file generated default Dbset(TableName) for me.
myDbContext.Table1.ToList();
myDbContext.Table2.ToList();
Can we have a ModelView Class which pull both table out with single line?
Instead of
Table1=myDbContext.Table1.ToList();
Table2=myDbContext.Table2.ToList();
can we have like
ModelView=myDbContext.ModelView;
Updated
public partial class ProductTb
{
public string ProductID { get; set; }
public string ProductArticleNumber { get; set; }
public string ProductName { get; set; }
}
public partial class ProductTbTWO
{
public string ProductID { get; set; }
public string ProductArticleNumber { get; set; }
public string ProductName { get; set; }
}
public class ProductModelView
{
public ProductTb{get;set;}
public ProductTbTWO{get;set}
}
Create a Partial Class of your DbContext and add your custom Code.
public partial class MyDbContext
{
private MyDbContext(string contextName) : base(contextName) { }
public static MyDbContextCreate() {
return new MyDbContext(ContextName);
}
public ProductModelView ModelView {// Get ProductTb and ProductTbTWO}
}
and use it var myDbContext= MyDbContext.Create() and myDbContext.ModelView
But I don't recommend to do something like that, Add a Service class to with public method to get your code, Data Layer shouldn't deal with View Models
i prefer using static class:
public static class Utilities
{
public static ProductModelView getProductViewModel()
{
using (var db = new myDbContext()
{
var vm = new ProductModelView();
vm.ProductTb = db.ProductTb.ToList();
vm.ProductTbTWO = db.ProductTbTWO.ToList();
return vm;
}
}
}
you can call it like:
var vm = Utilities.getProductViewModel();
Domain Model
public abstract class BaseClass
{
public int Id { get; set; }
public int Something1 { get; set; }
public int Something2 { get; set; }
public string Something3 { get; set; }
}
public class PQR1 : BaseClass
{
public int value1 { get; set; }
}
public class PQR2 : BaseClass
{
public int value2 { get; set; }
}
public class PQR3 : BaseClass
{
public int value2 { get; set; }
}
Context Class
public class PQRContext : DbContext
{
public PQRContext() : base ("PQR")
{
}
public DbSet<BaseClass> Baseclass { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BaseClass>().
Map<PQR1>(m => m.Requires("Type").HasValue("Value1"))
.Map<PQR2>(m => m.Requires("Type").HasValue("Value2"))
.Map<PQR3>(m => m.Requires("Type").HasValue("Value3"));
}
}
It'll create table like this:
But I don't know how to use this table while coding, I get stuck like this
So I can't access to another classes like PQR1, PQR2,PQR3 where as I have no reason to insert data into base class which is already abstract.
First option :
You are not restricted on DbSet creations. You can create many DbSet as much as you need for your derived classes like the code below and access them like you will do with other DbSet :
public DbSet<BaseClass> Baseclass { get; set; }
public DbSet<PQR1> PQR1s { get; set; }
public DbSet<PQR2> PQR2s { get; set; }
public DbSet<PQR3> PQR3s { get; set; }
You use the DbSet related to the derived you want for inserting into or requesting your context.
Second option :
For querying your context and get only the desired subclass entities you can use the generic method OfType<T> which act as a filter like this:
var myBaseClassList = myContext.BaseClass; // Retrieve all PQR1, PQR2 and PQR3 entities
var myPQR1List = myContext.BaseClass.OfType<PQR1>(); // Retrieve all PQR1
var myPQR2List = myContext.BaseClass.OfType<PQR2>(); // Retrieve all PQR2
var myPQR3List = myContext.BaseClass.OfType<PQR3>(); // Retrieve all PQR3
For inserting you can create an instance of your derived class and add it directly to your base class DbSet :
var pqr1 = new PQR1() { /* set my properties */ };
myCOntext.BaseClass.Add(pqr1); // EF knows how to insert data for classes that use TPH.
I am trying to wrap my head around the idea of Composition. Never used it before. I have a class that looks like this (thinned down):
public class AccountProfile
{
public string AccountNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public void GetAccountProfile()
{
AccountNumber = "123456"; // eventual these will become values from the database
FirstName = "John";
LastName = "Smith";
}
}
Then, in my view model, I'd like to have access to AccountNumber, FirstName, and LastName. I don't want to use inheritance, as this view model will need access to multiple external, unrelated classes. So far the model is simple:
public class AccountProfileViewModel
{
public AccountProfileViewModel() { }
}
Here's what I've tried so far, none which are correct:
public class AccountProfileViewModel
{
AP= new AccountProfile();
public AccountProfileViewModel() { }
}
That one (above) throws multiple errors and won't compile. I've also tried this:
public class AccountProfileViewModel
{
public AccountProfile AP { get; set; }
public AccountProfileViewModel() { }
}
This one (the one above) compiles just fine, but it throws a run-time error in the controller when I try and use it:
model.AP.GetAccountProfile();
The error: {"Object reference not set to an instance of an object."}
I'm out of ideas. Thanks!
you have to initialize the object at least.
public class AccountProfileViewModel
{
public AccountProfile AP { get; set; }
public AccountProfileViewModel() {
AP = new AccountProfile();
}
}
I think what you are trying to achieve is something like this:
public class AccountProfileViewModel
{
public AccountProfile AP { get; set; }
public AccountProfileViewModel() { }
}
or if AccountProfileViewModel really needs AccountProfile you can do
public class AccountProfileViewModel
{
public AccountProfile AP { get; set; }
public AccountProfileViewModel(AccountProfile profile) {
this.AP = profile;
}
}
and in your controller you can do something like this
public class controller {
public ActionResult Index(){
var vm = new AccountProfileViewModel();
var ap = //Get accountProfile
vm.AP = ap;
return View(vm);
}
}
or in the case of example where you need the AccountProfile
public class controller {
public ActionResult Index(){
var ap = //Get accountProfile
var vm = new AccountProfileViewModel(ap);
return View(vm);
}
}
you want AccountProfileViewModel to have an instance of the AccountProfile but you want to set it in the controller.
then in your view you can do Model.AP.AccountNumber for instance
If you need an object reference in this class then it's my personal preference to only create the object if it's required like so:
public class AccountProfileViewModel
{
private AccountProfile _ap;
public AccountProfile AP
{
get { return _ap ?? (_ap = new AccountProfile()); }
set { _ap = value; }
}
}
If you actually use yourObject.AP then it will have a reference created / return the existing one but if it's not used then no reference has been created.
I got dbset for table Functions in database and FunctionsContext: dbContext. I am implementing repository. In my interface I have only one function at the movement "GetFunctions". I got stuck in implementing class; method "GetFunctions" where I need to call FunctionsContext to get all list of available functions title from database and then send to controller class
I am using mvc5 asp.net and entity framework
dbContext
public class FunctionsContext : dbContext
{
public DbSet<App_Functions> Functions { get; set; }
}
model
[Table("Functions")]
public class App_Functions
{
[Key]
public int Function_ID { get; set; }
[StringLength(50)]
[Required]
public string Title { get; set; }
public int Hierarchy_level { get; set; }
}
Domain Class
public class Functions
{
public Functions()
{
}
public int Function_ID { get; set; }
public string Title { get; set; }
public int Hierarchy_level { get; set; }
}
IRepository
interface IFunctionRepository: IDisposable
{
IQueryable<Functions> GetFunctions { get; }
}
IRepository Implementation class
public class FunctionRepository : IFunctionRepository
{
private FunctionsContext fun_Context = new FunctionsContext();
public IQueryable<Functions>GetFunctions
{
?????????
}
}
what I want to implement in IQueryableGetFunctions
using (var db = new FunctionsContext())
{
var query = from b in db.Functions
orderby b.Function_ID
select b;
foreach (var item in query)
{
var a2 = item.Title;
}
}
I think the easiest way will be the following:
public IQueryable<Functions> GetFunctions()
{
return fun_Context.Functions.Select(x=>new Functions {
Function_ID = x.Function_ID,
Title = x.Title,
Hierarchy_level = x.Hierarchy_level
});
}
You have to add () after the method name, this declaration does not work 'public IQueryable GetFunctions'
IRepository Implementation class
public class FunctionRepository : IFunctionRepository
{
private FunctionsContext fun_Context = new FunctionsContext();
// For method declaration add the () after the method name
public IQueryable<Functions> GetFunctions()
{
return fun_Context.Functions;
}
}
[DisplayName("Planned Amt($):")]
public string PlannedAmount { get; set; }
[DisplayName("Unallocated Amt($):")]
public string UnallocatedAmount { get; set; }
I have this members in my class .Based on budgetType variable value i need to change the DisplayName Value for both the attributes. Please, let me know how to do that.
You should just be able to inherit from DisplayNameAttribute and override the DisplayName property:
public class DisplayNameExAttribute : DisplayNameAttribute
{
public override string DisplayName
{
get
{
// do what you want here.
return base.DisplayName;
}
}
}
I haven't actually tried to implement this, so it is possible that the DisplayName attribute is coded such that some other extension point will have to be used, but I'll try to confirm.
You can inherit from DisplayNameAttribute like this:
public class BudgetDisplayNameAttribute : DisplayNameAttribute
{
public BudgetDisplayNameAttribute(string pBaseName) : base(pBaseName) { }
public override string DisplayName
{
get
{
return My.BudgetType + " " + base.DisplayName;
}
}
}
Where, for this example, My.BudgetType is a public static string in a public static class:
public static class My
{
public static string BudgetType = "Quarterly";
}
And then apply the attribute to your property like this:
[BudgetDisplayName("Planned Amt($):")]
public string PlannedAmount { get; set; }
[BudgetDisplayName("Unallocated Amt($):")]
public string UnallocatedAmount { get; set; }
Finally, the part of your program that uses the DisplayName attribute of your properties will get the text:
"Quarterly Planned Amt($):" for the PlannedAmount property
"Quarterly Unallocated Amt($):" for the UnallocatedAmount property