Modify Model in MVC 5 EF5 after find function - c#

I need after loading the data from a model, automatically insert an information on a property of this type which do not come from the DB.
Exemple:
namespace project.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
public partial class MessageSource
{
public MessageSource()
{
this.messages = new HashSet<Message>();
}
public int id { get; set; }
public string category { get; set; }
public string message { get; set; }
public string message_translation { get; set; }
public virtual ICollection<Message> messages { get; set; }
}
}
id, category and message are DB table properties, message_translation no, after loading this model, always I will need to put automatically information in message_translation. How?

I do this:
public partial class MessageSource
{
public MessageSource()
{
this.messages = new HashSet<Message>();
}
public int id { get; set; }
public string category { get; set; }
public string message { get; set; }
public string message_translation { get; set; }
public virtual ICollection<Message> messages { get; set; }
public string getTranslate()
{
if(message_translation == null)
{
Message msg = messages.FirstOrDefault(m => m.language.Equals(Translate.Instance.getLanguage()));
if(msg != null)
{
message_translation = msg.translation;
}
else
{
message_translation = String.Empty;
}
}
return message_translation;
}
}
works good

public partial class MessageSource
{
private string _defaultLanguage;
public MessageSource(string defaultLang)
{
this.messages = new HashSet<Message>();
this._defaultLanguage = defaultLanguage ;
}
public int id { get; set; }
public string category { get; set; }
public string message { get; set; }
public string message_translation { get;
set{ value = getTranslation(_defaultLnag); }
public virtual ICollection<Message> messages { get; set; }
public string getTranslate(string lang)
{
var Translation = dbcontext.messages.Where(m=> m.Id == this.Id).FirstOrDefault().Translation.Where(t=>t.lang == lang).FirstOrDefault();
return Translation;
}
}
this solution assume that you are saving the translations in a separate table linked to the messages tables

messageSource m = new messageSource();
var m2 = // query your db using sql or entity framework
Then
m.id= m2.id;
m.category= m.category;
m.message= m2.message
m.message_translation= "vvvvvvv whatever"//do add thing here
m.messages = m2.messages;
Edit:
Another solution
Public class translation {
public int Id { get; set;}
public string language { get; set;}
public string text { get; set;}
}
Then you add in your messageSource model the following after removing message_translation
Public Icollection<translation> transMsg { get; set;}
Now suppose you have a msg that is translated into 13 languages; then the ICollection<transMsg> will have 13 item, and we need only the chinese translation
Do as follow:
First get your message
var myMsg = dbContext.messageSources.Where(m=>m.id== 6).FirstOrDefault();
This will not load any translation bec. We didnt use Include() , i.e. lazy loading
However, when we want the translation we pull it via another Linq query as follow:
var myMsgTranslation = myMsg.transMsgs.Where(t=>t.lang == "chinese").FirstOrDefault();
Or you load all the translations as follow
var myMsg = dbContext.messageSources.Where(m=>m.id== 6).Include(m=>m.msgTrans).FirstOrDefault();
And in yor View page u pull the default language as follow
#html.textBoxFor(model=>model.msgTrans.Where(t=>t.lang == "chinese"))
Desclaimer: not tested
Hope that help

Related

Combining data from 2 databases in MVC

I am fairly new to asp.net mvc and I currently have an application that shows a number of errors. I have 2 pages that contain Application Errors and Log Errors. The data comes from 2 different databases but I am wanting to display the data from both databases on one page.
The tables have headings with different names that mean the same thing e.g. ApplicationName in the Application Database is the same thing as LogName in the Log Database.
Below is a small example of what I currently have and an example of what I am wanting.
Current
Application Errors
ID ApplicationName ApplicationMessage ApplicationDate
1 Something Hello World 01/01/2015
2 Something Else Another Message 03/01/2015
Log Errors
ID LogName LogMessage LogDate
1 Some Log A log message 02/01/2015
2 Another Log Another Log Message 04/01/2015
What I Want
Internal Errors
ID Name Message Date
1 Something Hello World 01/01/2015
2 Some Log A log message 02/01/2015
3 Something Else Another Message 03/01/2015
4 Another Log Another Log Message 04/01/2015
At the minute, I have 2 separate models for each database but I think I need to merge both models into one model that combines them both but I am unsure on how to do this. How would I be able to merge both data sources together to display the data within the same page?
Current Models
Application
[Table("ELMAH_Error")]
public class ElmahError
{
[Key]
public System.Guid ErrorId { get; set; }
public System.String Application { get; set; }
public System.String Host { get; set; }
public System.String Type { get; set; }
public System.String Source { get; set; }
public System.String Message { get; set; }
public System.String User { get; set; }
public System.Int32 StatusCode { get; set; }
public System.DateTime TimeUtc { get; set; }
public System.Int32 Sequence { get; set; }
public System.String AllXml { get; set; }
}
Log
[Table("LogEntry")]
public class LogEntry
{
[Key]
public Int64 ID { get; set; }
public DateTime LogDate { get; set; }
public Int16 Priority { get; set; }
public string SourceClass { get; set; }
public string Category { get; set; }
public string Message { get; set; }
public string UserID { get; set; }
public string ProcessID { get; set; }
}
From the models, there are a number of fields that I would like to merge as well as fields that are not similar that I would also like to include. The model below shows exactly what I want but I just don't know how to implement it.
Internal Errors
public class InternalErrors
{
public string Id { get; set; } //L:ID && E:ErrorId
public int Priority { get; set; } //L:Priority
public string Application { get; set; } //L:SourceClass && E:Application
public string Message { get; set; } //L:Message && E:Message
public string Type { get; set; } //L:Category && E:Type
public string User { get; set; } //L:UserID && E:User
public string ProcessID { get; set; } //L:ProcessID
public DateTime Date { get; set; } //L:LogDate && E:TimeUtc
public int StatusCode { get; set; } //E:StatusCode
public string AllXml { get; set; } //E:AllXml
public int Sequence { get; set; } //E:Sequence
public int ErrorCount { get; set; } //E:ErrorCount
}
I hope this is enough information for you to provide an answer, if you need anything else, let me know.
Thanks in advance
if what you want is this
Internal Errors
ID Name Message Date
1 Something Hello World 01/01/2015
2 Some Log A log message 02/01/2015
3 Something Else Another Message 03/01/2015
4 Another Log Another Log Message 04/01/2015
then create a class with name InternalErrors as follows.
public class InternalErrors
{
public int ID;
public string Name;
public string Message;
public DateTime Date;
}
Now you can write a Linq Query as follows to get data from Application Errors and Log Errors and Perform union on it.
var AppErrors=from AE in _db.ApplicationErrors select AE;
var LogErrors=from LE in _dc.LogErrors select LE;
var internerrors=AppErrors.Union(LogErrors);
var InternalErrors=(from ie in internerrors select new InternalErrors()
{
ID=ie.ID,
Message=ie.ApplicationMessage,
Name=ie.ApplicationName,
Date=ie.ApplicationDate
}).ToList();
The viewmodel approach from MRebati is the best solution.
I often find it usefull to have a base class and different implementations:
public abstract class ErrorViewModel
{
public abstract int Id { get; }
public abstract string Name { get; }
}
public class ElmahErrorViewModel
{
public ElmahErrorViewModel(ElmahError instance)
{
this.Instance = instance;
}
public ElmahError Instance { get; private set; }
public int Id { get { return Instance.ErrorId; } }
public string Name { get { return instance.Appication; } }
}
that way you can create a List<ErrorViewModel> and add entries with
var items = from e in context.ElmahErrors
select new ElmahErrorViewModel(e);
list.AddRange(items);
var items2 = from l in context.LogEntrys
select new LogEntryViewModel(l);
list.AddRange(items2);
This is very usefull since you hide the details but you still can seprate the list and access the underlying object with
var elmahErrors = items.OfType<ElmahErrorViewModel>().Select(x => x.Instance);
There are many ways to provide data from the models to the View.
One is the ViewModel. It must contain the data you want to send to view. Look at this:
using System;
public class ErrorViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public DateTime Date { get; set; }
}
And in the Controller you need to Create a list of this ViewModel and populate it with your data.
you can use linq
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var elmahErrorList = new List<ElmahError>{
new ElmahError{ ErrorId = Guid.NewGuid(), Application = "Something",Message = "Hello World" , TimeUtc = DateTime.Now },
new ElmahError{ ErrorId = Guid.NewGuid(), Application = "Something Else",Message = "Another Message" , TimeUtc = DateTime.Now }
};
var logEntryList = new List<LogEntry>{
new LogEntry{ ID = 1, SourceClass = "Something",Message = "Hello World" , LogDate = DateTime.Now },
new LogEntry{ ID = 1, SourceClass = "Something Else",Message = "Another Message" , LogDate = DateTime.Now }
};
var internalErrorsList = new List<InternalErrors>();
var elmahErrorListinternalErrorses = elmahErrorList.Select(e => new InternalErrors
{
Id = e.ErrorId.ToString(),
Application = e.Application,
Message = e.Message,
Type = e.Type,
User = e.User,
Date = e.TimeUtc,
StatusCode = e.StatusCode,
AllXml = e.AllXml,
Sequence = e.Sequence
});
internalErrorsList.AddRange(elmahErrorListinternalErrorses);
var elmahErrorListlogEntryLists = logEntryList.Select(l => new InternalErrors
{
Id = l.ID.ToString(),
Priority = l.Priority,
Application = l.SourceClass,
Message = l.Message,
Type = l.Category,
User = l.UserID,
Date = l.LogDate
});
internalErrorsList.AddRange(elmahErrorListlogEntryLists);
internalErrorsList.ForEach(f =>
{
Console.Write(f.Id); Console.Write("\t");
Console.Write(f.Application);Console.Write("\t");
Console.Write(f.Message);Console.Write("\t");
Console.Write(f.Date);Console.Write("\t");
Console.WriteLine();
});
}
public class InternalErrors
{
public string Id { get; set; } //L:ID && E:ErrorId
public int Priority { get; set; } //L:Priority
public string Application { get; set; } //L:SourceClass && E:Application
public string Message { get; set; } //L:Message && E:Message
public string Type { get; set; } //L:Category && E:Type
public string User { get; set; } //L:UserID && E:User
public string ProcessID { get; set; } //L:ProcessID
public DateTime Date { get; set; } //L:LogDate && E:TimeUtc
public int StatusCode { get; set; } //E:StatusCode
public string AllXml { get; set; } //E:AllXml
public int Sequence { get; set; } //E:Sequence
public int ErrorCount { get; set; } //E:ErrorCount
}
public class ElmahError
{
public System.Guid ErrorId { get; set; }
public System.String Application { get; set; }
public System.String Host { get; set; }
public System.String Type { get; set; }
public System.String Source { get; set; }
public System.String Message { get; set; }
public System.String User { get; set; }
public System.Int32 StatusCode { get; set; }
public System.DateTime TimeUtc { get; set; }
public System.Int32 Sequence { get; set; }
public System.String AllXml { get; set; }
}
public class LogEntry
{
public Int64 ID { get; set; }
public DateTime LogDate { get; set; }
public Int16 Priority { get; set; }
public string SourceClass { get; set; }
public string Category { get; set; }
public string Message { get; set; }
public string UserID { get; set; }
public string ProcessID { get; set; }
}
}
Demo : https://dotnetfiddle.net/mrWGDn

Entity Framework objects being duplicated in the database

I am working with Entity Framework (code first) for the first time and I have a little problem.
I have a class called Taxi & one called Driver
Taxi has a reference to the Driver, you can see both classed below
public partial class Taxi
{
public Taxi()
{
}
public int TaxiId { get; set; }
public Driver Driver { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Color Colour { get; set; }
public string NumPlate { get; set; }
public int MaxPassengers { get; set; }
}
public partial class Driver
{
public Driver()
{
}
public int DriverId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string HomePhone { get; set; }
public string MobilePhone { get; set; }
public DateTime JoinedFirm { get; set; }
}
And I am saving the changed Taxi like this:
using (var db = new DataModel())
{
db.Configuration.ProxyCreationEnabled = false;
db.Taxis
.Where(x => x.TaxiId == CurrenltySelectedTaxi.TaxiId)
.ToList()
.ForEach(x =>
{
x.Make = CurrenltySelectedTaxi.Make;
x.Model = CurrenltySelectedTaxi.Model;
x.NumPlate = CurrenltySelectedTaxi.NumPlate;
x.Colour = CurrenltySelectedTaxi.Colour;
x.MaxPassengers = CurrenltySelectedTaxi.MaxPassengers;
x.Driver = CurrenltySelectedTaxi.Driver;
});
db.SaveChanges();
}
My problem is that the Driver gets duplicated the in database every time I save a taxi.
You can see the database here:
Can someone point me in the right direction,
Thanks
EDIT:
The drivers are in a combo box and are selected like this
private void cmbTaxiDriver_SelectedIndexChanged(object sender, EventArgs e)
{
using (var db = new DataModel())
{
db.Configuration.ProxyCreationEnabled = false;
Driver listSelected = (Driver) cmbTaxiDriver.SelectedItem;
CurrenltySelectedTaxi.Driver = db.Drivers.Where(x => x.DriverId == listSelected.DriverId).ToArray()[0];
}
}
And the combo box is populated like this:
listDrivers.Items.AddRange(db.Drivers.ToArray());
The only thing that I can possibly find based on the content you have provided is that CurrenltySelectedTaxi.Driver is a detached or new driver. Be careful to ensure that the object pointed to by CurrenltySelectedTaxi.Driver is an attached driver record.
An option you can do to help determine the status of that record is to put a breakpoint on that line and then look at the DbEntry record status.
Your design doesn't create a relationship between Taxi and Driver that's going to translate to a database. Try something like this:
public partial class Taxi
{
public Taxi()
{
}
public int TaxiId { get; set; }
public int DriverId {get; set; }
public virtual Driver Driver { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Color Colour { get; set; }
public string NumPlate { get; set; }
public int MaxPassengers { get; set; }
}
You may also want to add the following to the Driver object:
public virtual IEnumerable<Taxi> Taxis { get; set; }
So it turns out my issue is because i followed the tutorial on MSDN that says to recreate your context EVERYTIME you use it. Although this 'may' be good practice, in this instance it caused the problem.
If I make one context for the entire class it works as expected/

NullReferenceException thrown by MVC View Model

I'm trying to sort out this issue but as I'm learning a lot of this stuff as I go along I'd really appreciate it if someone could explain where I'm going wrong and/or some good resources where I can read up.
So, I have a model based on my Entity Framework model of my database and a viewmodel representing properties in that model. I've built a Kendo grid to display the data (defined in a js file) and the method in the contoller returns a Json result set. Trouble is, when I try to display a value in a joined db table, if there hasn't been a key value set, I get a nullreferenceexception error. Obviously I'm missing part of the puzzle here as there must be a way of coding this to stop it happening. Any help would be gratefully received!
My model is like this:
namespace TrainingKendoUI.Models
{
using System;
using System.Collections.Generic;
public partial class TRAINING_EMPLOYEE_COURSES
{
public int EMP_COURSE_ID { get; set; }
public int EMPLOYEE_ID { get; set; }
public int COURSE_ID { get; set; }
public Nullable<System.DateTime> DATE_ATTENDED { get; set; }
public Nullable<decimal> COURSE_COST { get; set; }
public string COURSE_RESITS { get; set; }
public Nullable<int> PROVIDER_ID { get; set; }
public Nullable<int> EMP_COURSE_STATUS_ID { get; set; }
public Nullable<int> VENUE_ID { get; set; }
public virtual TRAINING_COURSES TRAINING_COURSES { get; set; }
public virtual TRAINING_EMPLOYEE_COURSE_STATUS TRAINING_EMPLOYEE_COURSE_STATUS { get; set; }
public virtual TRAINING_EMPLOYEES TRAINING_EMPLOYEES { get; set; }
public virtual TRAINING_PROVIDERS TRAINING_PROVIDERS { get; set; }
public virtual TRAINING_VENUES TRAINING_VENUES { get; set; }
}
}
My controller method looks like this:
public JsonResult EmployeeCourses_Read()
{
var model = db.TRAINING_EMPLOYEE_COURSES;
var ViewModel = new List<EmployeeCoursesIntersectionViewModel>();
foreach (var employee in model)
{
ViewModel.Add(new EmployeeCoursesIntersectionViewModel(employee));
}
return Json(ViewModel, JsonRequestBehavior.AllowGet);
}
and my view model lilke this:
namespace TrainingKendoUI.ViewModels
{
public class EmployeeCoursesIntersectionViewModel
{
#region Constructors
public EmployeeCoursesIntersectionViewModel()
{
}
public EmployeeCoursesIntersectionViewModel(TRAINING_EMPLOYEE_COURSES model)
{
this.empCourseId = model.EMP_COURSE_ID;
this.employee = model.TRAINING_EMPLOYEES.FIRST_NAME;
this.course = model.TRAINING_COURSES.COURSE_NAME;
this.dateAttended = model.DATE_ATTENDED;
this.cost = model.COURSE_COST;
this.resits = model.COURSE_RESITS;
//These lines will produce a NullReference error if not set through the front end...
this.provider = model.TRAINING_PROVIDERS.PROVIDER_NAME;
this.status = model.TRAINING_EMPLOYEE_COURSE_STATUS.EMP_COURSE_STATUS;
this.venue = model.TRAINING_VENUES.VENUE_NAME;
}
#endregion
#region Properties
public int empCourseId { get; set; }
public string employee { get; set; }
public string course { get; set; }
public Nullable<System.DateTime> dateAttended { get; set; }
public Nullable<decimal> cost { get; set; }
public string resits { get; set; }
public string provider { get; set; }
public string status { get; set; }
public string venue { get; set; }
#endregion
}
}
Do a null check on the object before setting it, i.e.
this.provider = model.TRAINING_PROVIDERS == null ? ""
: model.TRAINING_PROVIDERS.PROVIDER_NAME;
and you'll have to do similar for status and venue
this.status = model.TRAINING_EMPLOYEE_COURSE_STATUS== null ? ""
model.TRAINING_EMPLOYEE_COURSE_STATUS.EMP_COURSE_STATUS;
this.venue = model.TRAINING_VENUES== null ? ""
model.TRAINING_VENUES.VENUE_NAME;

Updating List<T> in DbContext

I have a Model like this
public class Challenge
{
public int ID { get; set; }
public string Name { get; set; }
public string Blurb { get; set; }
public int Points { get; set; }
public string Category { get; set; }
public string Flag { get; set; }
public List<string> SolvedBy { get; set; }
}
public class ChallengeDBContext : DbContext
{
public DbSet<Challenge> Challenges { get; set; }
}
and then Controller like this. But I cannot update the List "SolvedBy", the next time I step through with the debugger, the list is still empty.
[HttpPost]
public string Index(string flag = "", int id=0)
{
Challenge challenge = db.Challenges.Find(id);
if (flag == challenge.Flag)
{
var chall = db.Challenges.Find(id);
if (chall.SolvedBy == null)
{
chall.SolvedBy = new List<string>();
}
chall.SolvedBy.Add(User.Identity.Name);
db.Entry(chall).State = EntityState.Modified;
db.SaveChanges();
//congrats, you solved the puzzle
return "got it";
}
else
{
return "fail";
}
}
is there any way around it to make a list of strings kept in the database?
EF don't know how to store an array in database table so it just ignore it. You can create another table/entity or use XML/JSON to store the list. You can serialize the list before saving and deserialize it after loading from database
A List<T> in a model would normally map to a second table, but in your DbContext you only have a single table. Try adding a second table.
public class ChallengeDBContext : DbContext
{
public DbSet<Challenge> Challenges { get; set; }
public DbSet<Solution> Solutions {get; set;}
}
public class Challenge
{
public int ID { get; set; }
public string Name { get; set; }
public string Blurb { get; set; }
public int Points { get; set; }
public string Category { get; set; }
public string Flag { get; set; }
public List<Solution> SolvedBy { get; set; }
}
public class Solution
{
public int ID { get; set; }
public string Name { get; set; }
}
Then your controller can use code along the lines of...
var chall = db.Challenges.Find(id);
if (chall.SolvedBy == null)
{
chall.SolvedBy = new List<Solution>();
}
chall.SolvedBy.Add(new Solution {Name=User.Identity.Name});
None of the above has been tested and I may have made some mistakes there, but the general principle I want to illustrate is the fact that you need another table. The List<T> represents a JOIN in SQL.

Saving from a view model to a model in ASP.NET MVC

I have two models, a code model and a tag model which are linked by a many to many relationship. I am trying to add a code entry that includes a possible selection of many tags using a view model (using check boxes for the tags in my view). I am getting the error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List'1[StoRed.Models.Code]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[StoRed.Models.CodeTagViewModel]'.
It feels like I need to somehow convert my data to the acceptable format before trying to save it into the table but I'm new to MVC and I am having trouble finding any useful information on the internet about my specific problem. Any help would be greatly appreciated.
The code model
public class Code
{
[Key]
public int CodeID { get; set; }
[Required]
[StringLength(30)]
public string Title { get; set; }
[Required]
[StringLength(150)]
public string Description { get; set; }
public DateTime DateAdded { get; set; }
public DateTime LastUpdated { get; set; }
[Required]
[StringLength(30)]
public string Project { get; set; }
[Required]
[StringLength(30)]
public string CMS { get; set; }
public int DotNetVersion { get; set; }
[Required]
[StringLength(150)]
public string Dependencies { get; set; }
[StringLength(30)]
public string Author { get; set; }
public string CodeFile { get; set; }
[Required]
[StringLength(100)]
public string TFSLocation { get; set; }
////Creates a relationship in the DB with Tag
//[ForeignKey("TagID")]
public virtual ICollection<Tag> Tags { get; set; }
////Purely for API
//[Required]
public int TagID { get; set; }
}
The Tag model
public class Tag
{
[Key]
public int TagID { get; set; }
[Required]
[StringLength(30)]
public string TagName { get; set; }
public virtual ICollection<Code> Code { get; set; }
}
The context
public class Context : DbContext
{
public DbSet<Code> Code { get; set; }
public DbSet<Tag> Tags { get; set; }
}
The view model
public class CodeTagViewModel
{
public Tag Tag { get; set; }
public Tag TagID { get; set; }
public List<Tag> Tags { get; set; }
public int CodeID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime DateAdded { get; set; }
public DateTime LastUpdated { get; set; }
public string Project { get; set; }
public string CMS { get; set; }
public int DotNetVersion { get; set; }
public string Dependencies { get; set; }
public string Author { get; set; }
public string CodeFile { get; set; }
public string TFSLocation { get; set; }
}
Relevant part of the code controller
[HttpPost]
public ActionResult Create(CodeTagViewModel codeTagViewModel)
{
if (ModelState.IsValid)
{
Code code = new Code();
Tag tag = new Tag();
var codeTag = new CodeTagViewModel();
code.Title = codeTagViewModel.Title;
code.Description = codeTagViewModel.Description;
code.DateAdded = codeTagViewModel.DateAdded;
code.LastUpdated = codeTagViewModel.LastUpdated;
code.Project = codeTagViewModel.Project;
code.CMS = codeTagViewModel.CMS;
code.DotNetVersion = codeTagViewModel.DotNetVersion;
code.Dependencies = codeTagViewModel.Dependencies;
code.Author = codeTagViewModel.Author;
code.CodeFile = codeTagViewModel.CodeFile;
code.TFSLocation = codeTagViewModel.TFSLocation;
code.Tags = codeTagViewModel.Tags;
db.Code.Add(code);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(codeTagViewModel);
}
Your best bet is to create some kind of provider/manager/service/factory/handler - choose a name that makes most sense in terms of the job it is doing within the flow of data through your system - that is responsible for taking the ViewModel and mapping the properties of the ViewModel into an instance of the domain model before persisting the domain model to the data store, either itself or by passing the hydrated domain model to a repository layer. You can either do this manually or by using something like AutoMapper. Here's a quick manual example:
Create a CommandHandlers folder in your web project with the interface and dependant handler:
public interface ICodeCommandHandler
{
int Save(CodeTagViewModel input);
}
public class CodeCommandHandler : ICodeCommandHandler
{
private IRepository<Code> repository;
public CodeCommandHandler(IRepository<Code> repository)
{
this.repository = repository;
}
public int Save(CodeTagViewModel input)
{
Code code = new Code();
Tag tag = new Tag();
code.Title = input.Title;
code.Description = input.Description;
code.DateAdded = input.DateAdded;
code.LastUpdated = input.LastUpdated;
code.Project = input.Project;
code.CMS = input.CMS;
code.DotNetVersion = input.DotNetVersion;
code.Dependencies = input.Dependencies;
code.Author = input.Author;
code.CodeFile = input.CodeFile;
code.TFSLocation = input.TFSLocation;
code.Tags.Add(tag);
return repository.Save(code);
}
}
Then in your controller, inject the ICodeCommandHandler in via constructor injection, the same as you do with the repository in the CodeCommandHandler:
private readonly ICodeCommandHandler commandHandler;
public CodeController(ICodeCommandHandler commandHandler)
{
this.commandHandler = commandHandler;
}
[HttpPost]
public ActionResult Create(CodeTagViewModel codeTagViewModel)
{
if (!ModelState.IsValid)
{
return View(codeTagViewModel);
}
var id = codeCommandHandler.Save(codeTagViewModel);
// maybe do something useful with the document id after save
return RedirectToAction("Index");
}
To keep the Repository nice and simple, here's how that could look:
public interface IRepository<T>
{
int Save(T entity);
}
public class CodeRepository : IRepository<Code>
{
public int Save(Code entity)
{
using (var context = new Context())
{
context.Code.Add(entity);
context.SaveChanges();
}
}
}
I've not gone into detail about the dependency injection side of things as that wasn't part of the question but this should give you an idea of where to start

Categories

Resources