Задайте вопросЗадайте вопрос
 

ОтвеченоEF error : EntitySet name could not be found

  • 2 июля 2009 г. 14:38minusone Медали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     
    Greetings all!

    I have a C# solution with a class library project called WL.Data that contains my .edmx file, repository interfaces, concrete repositories, and some partial classes extending those classes created in the .edmx by the EF. The .edmx model has various objects mapped to tables, such as UserProfile, Client, Site etc, which all derive from EntityBase.

    In a repository i have the following:


    private wlEntities db;

    public WLRepository()
    {
        db = new wlEntities();
    }

    public void SaveEntity(T entity)
    {
        db.AddObject(entity.GetType().Name, entity);
    }


    I am using the db.AddObject() method rather than a db.AddTo.... method because the objects i am adding derive from the abstract base class, EntityBase, thus there is no AddTo... option.

    My problem occurs when i try to execute this in a test. I get the following error:

    "Test method WL.UnitTests.EFRepositoryTests.EFRepository_SavesUserProfile threw exception: 
    System.InvalidOperationException: The EntitySet name 'wlEntities.UserProfile' could not be found.."

    Now the entity.GetType().Name returns "UserProfile" as expected, which is the type it should be looking for in the EF right?
    So why is it sending the value "wlEntities.UserProfile" instead?

Ответы

  • 2 июля 2009 г. 19:45Ido Flatow. Медали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     Отвечено

    AddObject's first parameter is the name of the entity set, and I assume that since your class derives from EntityBase, the name of the EntitySet is EntityBase or EntityBaseSet, so either use:
    db.AddObject("EntityBase", entity);

    If you want the entity set's name to be retrieved automatically, you can use the metadata:
    model.MetadataWorkspace.GetEntityContainer(model.DefaultContainerName, System.Data.Metadata.Edm.DataSpace.CSpace).BaseEntitySets.Where(bes => bes.ElementType.Name == typeof(T).Name).FirstOrDefault().Name

  • 3 июля 2009 г. 4:37Daniel Simmons - MSFTВладелецМедали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     Отвечено
    In addition you may find it interesting to realize that you can add a derived object to the AddTo method for the base class for its entityset.  Because the derived object is derived from the base class the types will work.

    To be more concrete, if I have a type Animal and an entityset Animals plus derived types Cat : Animal and Dog : Animal, then you will only have one entityset on your context (animals), and you will only have one AddTo method (AddToAnimals), but you can call myContext.AddToAnimals(myDog) and everything will work fine.  You could also call myContext.AddObject("MyContainer.Animals", myDog), but the key point is that the entityset is the one set that you have of all your animals.  You won't have a separate entityset for dogs and cats. *

    - Danny

    * The asterix is about the fact that what I said above is not 100% strictly true.  It is possible to create separate entitysets for dogs and cats if you want, but the designer won't allow you to do that--you would have to edit the XML by hand.  Also, even if you do create separate entitysets, if dog is derived from animal, then you can always add a dog instance to the animals set.  If you did create a set for dogs it would be a separate set which can only have dog instances or things dervied from dog, but it would not be a filtered view over the animals that just shows all the dogs or something like that.  Thing of an entityset as something like a List.  You can have a List<Animal> and it can contain instances of Animal or of Dog.  You can have another List<Dog> which can only contain instances of Dog, but if you put a Dog in your Animals list, you wouldn't automatically expect it to show up in the Dogs list as well.
    This posting is provided "AS IS" with no warranties, and confers no rights.

Все ответы

  • 2 июля 2009 г. 19:45Ido Flatow. Медали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     Отвечено

    AddObject's first parameter is the name of the entity set, and I assume that since your class derives from EntityBase, the name of the EntitySet is EntityBase or EntityBaseSet, so either use:
    db.AddObject("EntityBase", entity);

    If you want the entity set's name to be retrieved automatically, you can use the metadata:
    model.MetadataWorkspace.GetEntityContainer(model.DefaultContainerName, System.Data.Metadata.Edm.DataSpace.CSpace).BaseEntitySets.Where(bes => bes.ElementType.Name == typeof(T).Name).FirstOrDefault().Name

  • 3 июля 2009 г. 4:37Daniel Simmons - MSFTВладелецМедали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     Отвечено
    In addition you may find it interesting to realize that you can add a derived object to the AddTo method for the base class for its entityset.  Because the derived object is derived from the base class the types will work.

    To be more concrete, if I have a type Animal and an entityset Animals plus derived types Cat : Animal and Dog : Animal, then you will only have one entityset on your context (animals), and you will only have one AddTo method (AddToAnimals), but you can call myContext.AddToAnimals(myDog) and everything will work fine.  You could also call myContext.AddObject("MyContainer.Animals", myDog), but the key point is that the entityset is the one set that you have of all your animals.  You won't have a separate entityset for dogs and cats. *

    - Danny

    * The asterix is about the fact that what I said above is not 100% strictly true.  It is possible to create separate entitysets for dogs and cats if you want, but the designer won't allow you to do that--you would have to edit the XML by hand.  Also, even if you do create separate entitysets, if dog is derived from animal, then you can always add a dog instance to the animals set.  If you did create a set for dogs it would be a separate set which can only have dog instances or things dervied from dog, but it would not be a filtered view over the animals that just shows all the dogs or something like that.  Thing of an entityset as something like a List.  You can have a List<Animal> and it can contain instances of Animal or of Dog.  You can have another List<Dog> which can only contain instances of Dog, but if you put a Dog in your Animals list, you wouldn't automatically expect it to show up in the Dogs list as well.
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • 3 июля 2009 г. 5:41zeeshan hirani Медали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     
    in .net 4.0, you get ObjectSet, so u can also do like u do in linq to sql.
    db.Animals.Add(new Dog());
    db.Animals.Add(new Cat());

    instead of db.AddToAnimals(new Dog());

    I would actually go with the first option cuz it looks more natural.

    Zeeshan Hirani