简体   繁体   中英

Can I use and return EF4 code-first POCO entities as their interface?

Given the code later in the question, I am getting the following error from the EF4 code-first API:

The given property 'Roles' is not a supported navigation property. The property element type 'IRole' is not a supported entity type. Interface types are not supported.

Basically, I have a Repository similar to the following:

public class Repository : IRepository {
    private IEntityProvider _provider;
    public Repository(IEntityProvider provider) {
        _provider = provider;
    }
    public IUser GetUser(int id) {
        return _provider.FindUser(id);
    }
}

Notice that the IRepository.GetUser returns an IUser.

Let's say my IEntityProvider implementation looks like this.

public class EntityProvider : IEntityProvider {
    public IUser FindUser(int id) {
        /* Using Entity Framework */
        IUser entity;
        using (var ctx = new MyDbContext()) {
            entity = (from n in ctx.Users 
                  where n.Id == id 
                  select (IUser)n).FirstOrDefault();
        }
        return entity;
    }
}

The key here is that the IUser interface has a List<IRole> property called Roles. Because of this, it seems, the Entity Framework code-first cannot figure out what class to use to fulfill the IRole interface that property needs.

Below are the interfaces and POCO entities which would be used throughout the system and hopefully also used with EF4.

public interface IUser {
    int Id { get; set; }
    string Name { get; set; }
    List<IRole> Roles { get; set; }
}

public interface IRole {
    int Id { get; set; }
    string Name { get; set; }
}

public class User : IUser {
    public int Id { get; set; }
    public string Name { get; set; }
    public List<IRole> Roles { get; set; }
}

public class Role : IRole {
    public int Id { get; set; }
    public string Name { get; set; }
}

Am I going about this the wrong way? Is there a way to do this within the EF4 code-first API?

I can only think of the following:

  1. Some sort of shadow property (List<Role> DbRoles) that is used by EF4 code-first. Then use Data Annotations to make sure the actual List<IRole> is ignored by EF4.
  2. Create duplicate classes for all entities which EF4 code-first will use and then Map those to the official ones that implement the interface.

请记住,你需要使基类抽象化(用EF文档检查继承),我建议在其中没有任何内容的RootEntity,然后是一个带有一些常见信息的Base实体,如Id,InsertedBy,UpdatedBy like standart字段,它使一切变得更容易。

The use of Interfaces is not supported in EF 4 Code First (as of CTP5) and more than likely wont be supported in the RTM either. I would say make an abstract class in your DbContext to hold your objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM