微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – EF Code First通用检查没有公共ID属性的对象的存在?

编辑:在这个问题的底部回答

好的,所以我有一些通用的EF功能(我从这里得到了大部分功能),但它们似乎没有用.

我有3节课:

public class Group : Entity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public virtual GroupType GroupType { get; set; }

    public virtual ICollection<User> Users { get; set; }
}
 public class GroupType: Entity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

 public class User: Entity
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<Group> Groups { get; set; }
 }

我的CRUD操作:

public void Insert(TClass entity)
    {
        if (_context.Entry(entity).State == EntityState.Detached)
        {
            _context.Set<TClass>().Attach(entity);
        }
        _context.Set<TClass>().Add(entity);
        _context.SaveChanges();
    }

public void Update(TClass entity)
    {
        DbEntityEntry<TClass> oldEntry = _context.Entry(entity);

        if (oldEntry.State == EntityState.Detached)
        {
            _context.Set<TClass>().Attach(oldEntry.Entity);
        }

        oldEntry.CurrentValues.SetValues(entity);
        //oldEntry.State = EntityState.Modified;

        _context.SaveChanges();
    }

public bool Exists(TClass entity)
    {
        bool exists = false;

        if(entity != null)
        {
            DbEntityEntry<TClass> entry = _repository.GetDbEntry(entity);
            exists = entry != null;
        }

        return exists;
    }

public void Save(TClass entity)
    {
        if (entity != null)
        {
            if (Exists(entity))
                _repository.Update(entity);
            else
                _repository.Insert(entity);
        }
    }

最后我用以下方法调用代码

public string TestCRUD()
    {

        UserService userService = UserServiceFactory.GetService();
        User user = new User("Test","Test","TestUser") { Groups = new Collection<Group>() };

        userService.Save(user);
        User testUser = userService.Getone(x => x.UserName == "TestUser");

        GroupTypeService groupTypeService = GroupTypeServiceFactory.GetService();
        GroupType groupType = new GroupType("TestGroupType2",null);

        groupTypeService.Save(groupType);

        GroupService groupService = GroupServiceFactory.GetService();
        Group group = new Group("TestGroup2",null) { GroupType = groupType };
        groupService.Save(group);

        user.Groups.Add(group);
        userService.Save(user);

        return output;
    }

当我到达:

user.Groups.Add(group);
 userService.Save(user);

我收到以下错误

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

具有以下内部异常:

The INSERT statement conflicted with the FOREIGN KEY constraint “User_Groups_Source”. The conflict occurred in database “dbnAME”,table “dbo.Users”,column ‘Id’.

问题:

1)Exists总是返回true,即使实体刚刚在内存中创建,因此insert实际上永远不会被调用Save方法中的Update,我想这是因为我完全不了解DbEntityEntry因为它本身和Entry.Entity都是永远不会.我如何检查存在?

2)即使所有代码都在TestCRUD中运行直到最后,这些实体实际上都没有保存到数据库中.我很肯定我的数据库设置正确,因为我的自定义初始化程序正在丢弃并始终重新创建数据库并每次都插入种子数据.这可能是因为更新始终按照编号1中的说明进行调用.

任何想法如何解决

编辑:答案

假设,问题是存在总是返回true,因此插入从未被调用.我通过使用反射来获取主键并将其插入到find方法中来修复此问题,以便像这样存在:

public bool Exists(TClass entity)
    {
        bool exists = false;

        PropertyInfo info  = entity.GetType().GetProperty(GetKeyName());
        if (_context.Set<TClass>().Find(info.GetValue(entity,null)) != null)
            exists = true;

        return exists;
    }

所有其他方法开始按预期工作.但是,我在同一行上遇到了不同的错误

user.Groups.Add(group);
userService.Save(user);

这是:

Violation of PRIMARY KEY constraint ‘PK_GroupTypes_00551192′. Cannot insert duplicate key in object ‘dbo.GroupTypes’.
The statement has been terminated.

我将把它作为一个新问题发布,因为它是一个错误,但它确实解决了第一个问题.

解决方法

How can I check for an exists?

我通常看到人们检查实体是否已经存在的方式是检查其Id属性是否大于零.您应该能够使用带有Id属性的接口,或者(如果您希望实体具有多个键属性),您可以让每个实体覆盖一个抽象基类,覆盖Exists属性以检查其自己的ID属性认值.或者您可以使用反射自动查找ID属性,as explained here.

我怀疑,如果您正确插入新项目而不是尝试更新它们,其余问题将会消失.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐