I'm creating a timesheet with ASP.Net MVC.
Therefore, I need to save date values and time values in my database.
My datafields actually are type of datetime:
[Required]
public DateTime TimesheetDate { get; set; }
[Required]
public DateTime BeginOfWork { get; set; }
[Required]
public DateTime EndOfWork { get; set; }
Now, if I'd like to save a time-value of 07:30, the model to save contents something like: 01.01.0100 07:30:00
With this, the saveChanges Function fails. So how can I store times in a database, so that I could calculate later with them?
Which type of data should the field have?
Thanks Carsten
Related
I have an entity in my database linked up with multiple entities and I need to store historical data for the changes (insert ,updates and delete) in the base entity as well as children entities.
Now the approach we are thinking of adopting is to keep every data in the corresponding history entity. The base table looks like this :
public partial class Con
{
public Guid Id { get; set; }
public string Note { get; set; }
...
public virtual ICollection<Document> Document { get; set; }
public virtual ICollection<ConLine> ConLine { get; set; }
public virtual ICollection<Leg> Leg { get; set; }
}
And the historical table looks like this, I am not sure about how to design the history table to hold linked tables data:
public partial class ConHistory
{
public Guid Id { get; set; }
public Guid ConId { get; set; }
public int TransactionId { get; set; }
...
public virtual ICollection<Document> Document { get; set; }
public virtual ICollection<ConLine> ConLine { get; set; }
public virtual ICollection<Leg> Leg { get; set; }
}
How do I approach this problem and What are the best industry practices? My main concern is when a child's data is being changed how do I log in to parent history table and the corresponding child history table.
For simple time-series data, keeping a separate table with a copy of the modifiable fields is a perfectly valid approach. Unfortunately, in your case you would also need to make a copy of each of the linked tables as well, so that you can maintain consistent foreign keys - e.g. DocumentHistory, ConLineHistory, LegHistory. It's a lot of repetitive code. And then you have to consider, what happens to all the historical records when the schema changes?
Personally, I would store this information as json, in a text column. All the fields that you search on should be in sql, so that you can index it, but the rest can be serialized to a json string:
public partial class ConHistory
{
public Guid Id { get; set; }
public Guid ConId { get; set; }
public int TransactionId { get; set; }
public Guid ModifiedByUser { get; set; }
public DateTime Date { get; set; }
// Serialize the rest of the `ConHistory` fields to a json object, and store them here
public string Json { get; set; }
}
Sql also has the JSON_VALUE function, and there are some examples of using this in Entity Framework, if you do need to get values out of the json string for querying.
I have an mvc5 application that is connected to a EF database. Some fields in this database are meant to be autogenerated as declared in SQL, but when used in MVC and upon inserting records, the GUID only contains the value of 0 for all records. How can I resolve this? Any help will be appreciated. Thanks.
Model class:
public partial class Store
{
public int StoreID { get; set; }
public int CustomerID { get; set; }
public string StoreName { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public System.Guid StoreUID { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int StoreNumber { get; set; }
public string StoreLogo { get; set; }
public string StoreLogoPath { get; set; }
public string StoreAddress { get; set; }
public string StoreCity { get; set; }
public string StoreRegion { get; set; }
public string StoreCountry { get; set; }
public virtual Customer Customer { get; set; }
}
Both StoreUID and StoreNumber supposed to be autogenerated fields. Below is an example how its supposed to be when a new store is inserted, however currently, storeNumber and StoreUID both just return 0.
You need to add defaults to your database table to generate the fields.
ALTER TABLE [dbo].[Store] ADD DEFAULT (newid()) FOR [StoreUID]
ALTER TABLE [dbo].[Store] ADD DEFAULT (myfuncthatreturnsanint()) FOR [StoreNumber]
This isn't really an Entity Framework feature. EF needs to be aware of these column types to generate the appropriate SQL. What you require is something that's actually achieved from the database. For Model First, I got the auto generated int Id functionality by modifying the T4 template that ships with EF to write the appropriate SQL, but it really is database functionality. StoreNumber is a different case since SQL server only allows one identity column.
For your database, your StoreUID column specification should be:
StoreUID uniqueidentifier not null DEFAULT newid()
You don't specify if you're dealing with model first or code first, or if you're building something new, so you may have to modify your existing table for this.
EDIT
If you're using model first, ensure that in your model the Store Generated Column is set to Identity for the StoreUID value to be server generated. If not, and you're not worried about who/what creates the GUID, then create a default constructor for Store, if you don't already have one. Then in there add StoreUID = Guid.NewGuid();.
For StoreNumber, SQL server doesn't support multiple columns with auto incrementing integers. You'd need to research a number of strategies for inserting it.
A number are listed here and here. Essentially make StoreNumber a function of StoreID with Computed Columns, or use an independent Sequence:
ALTER TABLE Store DROP COLUMN StoreNumber;
GO
ALTER TABLE Store ADD StoreNumber AS StoreID + 550000;
I have been trying to sort DateTime column in asp.net mvc webgrid.
Here is my code:
grid.Column(header: "Product Purchased Date",columnName:"PurchasedDate" canSort: true,format: #<text>
#item.PurchasedDate.ToString("MM/dd/yyy")</text>
when i tried using above code i am getting this errors:
cannot convert from 'lambda expression' to
'System.Func'
The best overloaded method match for System.Web.Helpers.WebGrid.Column(string, string, System.Func, string, bool)' has some invalid arguments.
if i apply the above code without using columName i am unable to perform sorting.
Apologize if i missed anything.
I'd recommend that, if you want to sort it as a string, add a function within your Model object that returns the value as a string instead of converting it inline. So there would be a field such as PurchasedDateAsString on the object.
For instance this is something I used in a recent project. The field DateRange is returned as a string and can be sorted upon just like it was a "base" field:
public class PeriodView
{
[Key]
public int PeriodId { get; set; }
public string Name { get; set; }
public int Number { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int Year { get; set; }
public string Month { get; set; }
public string DateRange
{
get
{
var start = String.Format("{1}-{0}",
CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(StartDate.Month).Substring(0, 3),
StartDate.Day);
var end = String.Format("{1}-{0}",
CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(EndDate.Month).Substring(0, 3),
EndDate.Day);
return String.Format("{0} to {1}", start, end);
}
}
}
If you convert DateTime to string and format it, the WebGrid will sort the column as a string, which is not correct for DateTime Format Column expected result.
I'm having issues with a date property not binding correctly using TryUpdateModel in MVC.
I am using a POCO class and a corresponding viewModel.
public class ContactModel
{
public int Id { get; set; }
[Display(Name = "First Name")]
[StringLength(50)]
[Required(ErrorMessage = "First name must be entered.")]
public string ContactGivenName { get; set; }
[Display(Name = "Last Name")]
[StringLength(50)]
[Required(ErrorMessage = "Last name must be entered.")]
public string ContactFamilyName { get; set; }
....
[Display(Name = "Date of Birth")]
public DateTime? DateOfBirth { get; set; }
}
the entity class:
public class Contact
{
[Key]
public int Id { get; set; }
[StringLength(50)]
[Column(TypeName = "varchar")]
public string ContactFamilyName { get; set; }
[StringLength(50)]
[Column(TypeName = "varchar")]
public string ContactGivenName { get; set; }
...
[Column(TypeName = "date")]
public DateTime? DateOfBirth { get; set; }
}
and in my controller :
[HttpPost]
[GridAction]
public virtual ActionResult UpdateContact(int id, FormCollection form)
{
//Find a customer whose CustomerID is equal to the id action parameter
var c = _contactService.Get(id);
if (c != null)
{
//Perform model binding (fill the customer properties and validate it).
if (TryUpdateModel(c, form))
{
The _contactService.Get returns the instance from EntityFramework.
The TryUpdateModel binds string properties like first and last name correctly, but despite a lot of tries, I can't get it to bind the date of birth.
I suspect it's a formatting issue of some kind but cannot find what it is.
When I debug, I can see in the FormCollection that the date is correctly there, with the value that was input in the view so the data is definitely passed on to the controller.
the value passed to the controller is in format :
yyyy-MM-dd
I tried modifying this on the fly with multiple format without success.
Any ideas what I'm doing wrong here ?
Thanks a lot
Well, first, I have no idea why you're using TryUpdateModel.. That's pretty archaic.
Second, it sounds to me like you have not set your culture to accept the format you expect. Add the following to your web.config if your browser is defaults already set to the correct culture:
<system.web>
<globalization culture="auto" uiculture="auto" enableclientbasedculture="true">
</globalization>
</system.web>
If you want to force a culture, then set the culture you wish in this setting.
the globalization didn't help and is actually already set, however I realized there's a custom binder for Datetime and that is probably where my problem is.
thanks
I am using MVC to generate my database. I have the following code structure in my UserProfile class:
[KeyAttribute()]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
This generates the database fine, but when I try to insert a record it says UserId cannot be null. I cannot figure out why it isn't auto generating an Id integer.
This was because I had some issues updating the database. Needed to manually drop this table and re-create it. Is working fine now.