I would like to get the max length of a column I have defined using EF code first. I need to ensure that the value inserted does not exceed the max length:
this.Property(t => t.COMPANY_ID)
.HasMaxLength(30);
Any suggestions?
The way I understood your question, your real need seems to be that you want to make sure that a property of an entity (in this case the COMPANY_ID) does not exceed a certain maximum length (in this case 30).
Instead of performing manual checks like that, you can consider making use of Data Annotations (System.ComponentModel.DataAnnotations and System.ComponentModel.DataAnnotations.Schema), especially since you're using code first anyway. Something like this:
public class MyEntity
{
[MaxLength(30)]
public string MyProperty {get; set;}
[Column(TypeName="Date")]
public DateTime MyDate {get; set;}
}
You can set more than just the maximum length. As you can see above you can specify what data type should reflect in your database. You can also specify if a property is required and many more. EF will manage this for you automatically and will raise exceptions for you if your entities do not meet the criteria set by your data annotations. If you use MVC scaffolding, it can automatically generate validations as well that are consistent with the annotations you've specified for your entities.
Related
I have couple of DTOs that I am using in WEB API and I have noticed that I am reusing same properties over and over again.
For example
public class Response
{
public int Id {get;set;}
public DateTime CreatedOn {get;set;}
public string Name {get;set;}
public string Code {get;set;}
}
public class InsertRequest
{
public string Name {get;set;}
public string Code {get;set;}
}
Is there really a need to specify InsertRequest for a resource, since DTOs are processed later in the code? It could be misleading to have property Id available in code even if Id would not be inserted.
On the other hand if Id is declared as nullable, it can be misleading since Id in Response should not be nullable, so I am in doubt should these two request be split or should they all be in one representing a resource?
The situation you describe is pretty common for situations where you have to create / update entities.
I would recommend you keep yours as they are. CreatedOn makes no sense when you want to update and Id, well, it'll never change once created, so again, it makes no sense to have it in a change entity. Plus, chances are that you will provide your Id in the route so the actual entity doesn't need it anyway:
PUT against:
www.somedomain.com/entity/id
entity doesn't need id field as its coming from the URI.
Yes, you can argue that you will end up with entities with duplicate fields, but at the same time you'll have a clean API which makes sense and that's more important as this is what the clients will be seeing and using.
One more thing, I am in favor of keeping a clear naming convention so if one entity is InsertRequest then the other will be UpdateRequest.
I am learning about the POCOs and while I like a lot of the concepts, I think I am not quite getting it.
I have a problem like the following:
I have one sproc which returns multiple columns and values against these columns which dynamically build inside the sproc based on certain conditions.
e.g based on the input, one of the below result should return,
1)
Id -- Name -- Age
1 Peter 25
2 Janit 53
2)
Id -- Provider Name -- Provider Type
5 C. A hospital
I cant create class for these dynamic columns, therefore I fetch records using dynamic object and POCO DB.
List<dynamic> list = db.fetch<dynamic>(sql);
Problem occurs when somebody else call the function with different parameter then result keeps the column information for first call of POCO and result for desire one.
Id -- Name -- Age
5 C. A hospital
this discrepancy causing runtime error.
Can you please help me to resolve this issue?
or how can I define class for this kind of scenario?
Hope I explained my problem in detail manner.
You can define a POCO class just to grab the results. I use plenty of them. PetaPoco will fill only the fields that the SP returns.
Create a POCO with all columns you expect to be returned from the dynamic SP in a manner like the following:
public class PocoName
{
public int Id {get; set;}
public string Name {get; set;}
public int Age {get; set;}
public string ProviderName {get; set;}
public string ProviderType {get; set;}
...
}
Then call the function as follows:
List<PocoName> list = db.fetch<PocoName>(sql);
Every time you run the sproc with different input parameters, only the columns returned by the sproc will be populated within your POCO.
Though it's a 3 years old post, I came across a similar issue recently. Hopefully the workaround will help someone who encounters this in future.
PetaPoco keeps object definitions cached. So any db.fetch/db.query with diff parameters to the same SP will return the first call's object definition when we are expecting to have diff dynamic object list as result. I tried to cache burst, but couldn't find a way. Maybe there's option/config, but I haven't tried that far. If anyone knows the way to cache burst, please do share.
Since it is not practical to have Defined POCO classes to fit the dynamic nature of this case (as mentioned earlier by author), I tried returning DataTable and then converted it to dynamic object list which is working as expected.
Thanks
I have the following code in my context, and no explicit table-class mapping, yet my database keeps getting created (by my DropCreateDatabaseIfModelChanges initializer) with an EmployeeStatus table, not EmployeeStatuses. Is there a known issue with this, or am I going insane or what?
public DbSet<Department> Departments { get; set; }
public DbSet<EmployeeStatus> EmployeeStatuses { get; set; }
All my other tables are named exactly after their DbSet names, as I expect.
Entity Framework uses its pluralization service to infer database table names based on
the class names in the model—Destination becomes Destinations, Person becomes
People, etc. By convention, Code First will do its best to pluralize the class name and use the results as the name of the table. However, it might not be the same as your
table naming conventions.
You can use the Table Data Annotation to ensure that Code First maps your class to
the correct table name.
Is there a way to tell EF 4.3+ not to update some fields?
We have a standard in the DB where each table has a 'CreatedBy' column. I would like to make sure that it is impossible to update that column.
The safest I see it would be to tell EF not to map the corresponding properties but just for the update.
Is there a way to do that?
If you are using code first you can use the DatabaseGenerated attribute to configure the property as Computed.
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string Foo { get; set; }
I have a model as below:
public class Post
{
public int Id {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
public virtual ICollection<Reader> Readers {get;set;}
public int Value {get;set;}
}
The rule is Value = Comments.Count * 2 + Readers.Count.
What is the right and convenient way to deal with the "computed" property of "Value"?
I think it is the best that the "Value" can be calculated and saved automatically when Comments or Readers add/remove element.
but the "DatabaseGeneratedAttribute" seems no use here.
Thank you!
This is not supported. There is no way to make Value available for linq-to-entities queries if it is not mapped to database column. In case of EF using EDMX for mapping this can be sometimes solved by using custom mapped SQL function or model defined function but code first mapping doesn't support anything of that. Other way is to create database view and map your entity to view but in such case entity will be read only.
Once you use .NET code for defining value it is always only client side property computed from data loaded from database. If you don't want to recompute property every time you need observable collections with event handler changing precomputed value each time the collection changes.
DatabaseGenerated attribute just marks your property as generated by database - in such case you cannot change its value and database must ensure that correct value will be stored in your table.
I think your column value is based on two mapped properties. Use NotMappedAttribute to Exclude a Property from the Database Schema and Load values in runtime.
public class Post
{
public int Id {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
public virtual ICollection<Reader> Readers {get;set;}
[NotMapped]
public int Value
{
get return Comments.Count * 2 + Readers.Count;
}
}
You may use the DatabaseGenerated attribute and then create triggers in the db for calculating the Value. You can create the triggers in the migrations, or db seed method.