I create a model that hasnt any relation to another tables with EF.
when I add it in the context and run app for create database i had an Error in Application-start:
One or more validation errors were detected during model generation:
System.Data.Edm.EdmEntityType: : EntityType 'UrlHelper' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntityType: : EntityType 'RequestContext' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntityType: : EntityType 'HttpContextBase' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntityType: : EntityType 'Exception' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntityType: : EntityType 'Type' has no key defined. Define the key for this EntityType.
Code in my global.asax is like below:
public class MyInitializer
: DropCreateDatabaseIfModelChanges<DBTa>
{
}
protected void Application_Start()
{
//for creating and initializing database
System.Data.Entity.Database.SetInitializer(new MyInitializer());
**DBTa db = new DBTa();**//Error shows here
db.Database.Initialize(true);
//
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
but when i removed model from app my problem solved, but i need this Model.
please help
thanks a lot
You should set "key" property in your 'UrlHelper' model.
If you use EF code first - in your model you should add attribute [Key] to one of its properties.
If you use model first approach - in your model you should mark one of properties as primary key.
If you use Database first approach - you should create primary key in table.
Related
I am using ServiceStack.Ormlite, and also make heavy use of the automatic handling of enums whereby they are stored in the db as strings but retrieved and parsed nicely back into Enums on retrieval, so I can do easy type-comparison - say, for a property "UserRole" in the db/table class "User" of enum type "UserRoleEnum" (just for demonstration).
This works great.. until I want to use the enum property to define a multi-column unique constraint
CompositeIndexAttribute(bool unique, params string[] fieldNames);
like:
[CompositeIndex(true, nameof(UserId), nameof(UserRole)]
public class User
{
public long UserId {get;set;}
public UserRoleEnum UserRole {get;set;
}
(as per :
How to Create Unique Constraint with Multiple Columns using ServiceStack.OrmLite? ).
At which time i get:
System.Data.SqlClient.SqlException
Column 'UserRole' in table 'User' is of a type that is invalid for use as a key column in an index.
I currently see options as:
a) Define UserRole as a string (isntead of UserRoleEnum ) in the table entity class and lose the Enum use.... having to manually test the value each time to confirm that the db value is one that i expect in my business logic later
b) Continue to use UserRoleEnum but lose the ability to declare multicolumn uniqueconstraints using the class attribute, and probably have to create these manually using a subsequent db migration script?
Is there any way to make the enums and the multicolumn constraint play nicely, out of the box?
This issue was because enum properties were using the default string definition fallback of VARCHAR(MAX) which SQL Server doesn't let you create indexes on whereas the column definition of a string property is VARCHAR(8000).
This issue is now resolved from this commit which now uses the VARCHAR(255) string definition of the EnumConverter Type Converter. This change is available from v4.5.5 that's now available on MyGet.
Otherwise you can also change the size of the column definition to match a string property by adding a [StringLength] attribute, e.g:
[CompositeIndex(true, nameof(UserId), nameof(UserRole))]
public class User
{
public long UserId { get; set; }
[StringLength(8000)]
public string UserRole { get; set; }
}
I am using Entity Framework code first with a generic repository pattern with ASP.NET MVC. I have two tables Category and Product.
My model class of product is like this
Public class Product
{
public int ProductID{get;set;}
Public int CategoryID{get;set;}
[ForeignKey("CategoryID")]
public virtual Category Category{get;set;}
[NotMapped]
public string CategoryName{get;set;}
}
The model is binding correctly as long as I am getting data using DBContext.
But I am having a problem when I am getting list of products from stored procedure mapped to Product object. So it is not mapping the Category property of Product object and hence I cannot able to get Category.CategoryName.
So I added a new property with [NotMapped] attribute in product class as CategoryName. But it is also not binding from stored procedure.
And if I remove the [NotMapped] attribute then it is correctly binding from stored procedure but error occurs again when getting product by DbContext (Linq).
Please help me in this regards.
You don't need to add an extra property, use the DbSet.SqlQuery method for queries that return entity types. The returned objects must be of the type expected by the DbSet object, and they are automatically tracked by the database context unless you turn tracking off.
var products= _context.Products.SqlQuery("storedProcedureName",params);
The columns returned by SP should match the properties of your entity type otherwise, it will throw an exception.
After execute your SP, you should be able of get the CategoryName through your Category navigation property:
var catName=someProduct.Category.CategoryName;
On the other hand, the returned data by the Database.SqlQuery isn't tracked by the database context, even if you use this method to retrieve entity types. If you want to track the entities that you get after execute your SP using this method, you can try this:
//Attach the entity to the DbContext
_context.Product.Attach(someProduct);
//The Category navigation property will be lazy loaded
var catName=someProduct.Category.CategoryName;
If you have disabled lazy loading you can load explicitly your navigation property:
//Load the Category navigation property explicitly
_context.Entry(someProduct).Reference(c => c.Category).Load();
I have a block of code that is not working as I thought it would.
I have set an Entity up as follows and have a previous guid.
parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;
Now when I do a check with a statement:
if (parentEnt.Contains("attribute_field")) {
parentEnt["attribute_field"] = "test";
}
The above will never be called because the if statement fails.
However, if I remove the if statement. I am able to actually assign and run the code:
parentEnt["attribute_field"] = "test";
Is there something I am missing with the Contains Method? I thought it was used to check if the Entity contains the attribute?
On the Entity class, you can always assign an attribute like the example you provided whether or not it exists. If it exists, it will overwrite it (which is what you discovered).
So
parentEnt["attribute_field"] = "test";
Will always work, whether or not the attribute already has a value assigned.
When you run the constructor for a CRM entity object, and assign it a guid
Like
Entity parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;
you are creating a new object of the entity type with the 'vehicle_ent' logical name and a id of 'guid' At this point all the attribute/properties that belong to an entity with that name, are not created along with the entity object, and you only have an Entity class object with a LogicalName and id set.
If you want to check if an entity record with that id contains a certain attribute, you need to fetch is from the database, using your the organization service, like
ColumnSet attributes = new ColumnSet(true);
parentEnt = _service.Retrieve("vehicle_ent", guid, attributes);
After the retrieve is called you can check if the entity record contains the attribute you need to check.
I just add a couple of things:
The syntax entity[attributename] and entity.Attributes[attributename] are equivalent, the reason can be found inside the Entity metadata:
public object this[string attributeName] { get; set; }
the method maps at entity level the Attributes property (the type of this property is AttributeCollection an inherit from DataCollection<string,object> and the base type is an IEnumerable<KeyValuePair<TKey, TValue>>)
DataCollection contains this method:
// Summary:
// Gets or sets the value associated with the specified key.
//
// Parameters:
// key:
// Type: TKey. The key of the value to get or set.
//
// Returns:
// Type: TValue The value associated with the specified key.
public virtual TValue this[TKey key] { get; set; }
this method adds the key (our attributename) inside the collection if the key is not present before. For this you can assign a value to an attribute without using the Contains method first. Of course when you read the value you need to check if the key is present, this is the purpose of the Contains method, but to read the values the GetAttributeValue can be used as well (but it's necessary to pay attention to the default values returned when the attribute is not inside the collection)
I want to get the ID which was passed in the URL but it seems something goes wrong!
This is my routes.php
Route::get('/poste/{idp}',array('before' => 'members_auth',function($id){
//dd($id);
$post =Posts::where('idp','=',$id) -> get();
$titre=$post->titre;
$desc=$post->description;
return View::make('showPost',array('title'=>$titre,'description'=>$desc));
}));
And this is my View
<a href="/poste/{{$userpost->idp}}">
The error was Undefined property: Illuminate\Database\Eloquent\Collection::$titre
It is quite common issue when you start with Eloquent ORM. Basically get() method always returns Collection of objects, even if there is only one found. Sure enough Collection object has no titre property. If idp is primary key for your Post model, you should use find() or findOrFail() method instead.
$post = Posts::find($id);
As Laravel documentation states:
Note: Eloquent will also assume that each table has a primary key
column named id. You may define a primaryKey property to override this
convention. Likewise, you may define a connection property to override
the name of the database connection that should be used when utilizing
the model.
You are free to override your primary key.
class Posts extends Eloquent
{
protected $primaryKey = 'idp';
}
I'm not sure what I'm doing wrong here. The table "class1class2" is not being recognised.(See code below). I want to be able to use the junction table
Context
public class context: DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<class1>()
.HasMany(c => c.listofclass2).WithMany(i => i.listofclass1)
.Map(t => t.MapLeftKey("class1ID")
.MapRightKey("class2ID")
.ToTable("class1class2"));
}
}
Implementation:
context db = new context();
var r= db.class1class2;
class1class2 in the implementation code is not recognised
Yes it is not recognized because it doesn't exist. When you map many-to-many relation this way there is no class used for the junction table. It is handled transparently through your navigation properties listOfClass2 and listOfClass1.
If you want to have access to the junction table (which is useful only if the junction table contains additional data - not only foreign keys) you must create a class for that and map two one-to-many relations with this new class instead.