【问题标题】:Generic save method通用保存方法
【发布时间】:2013-05-15 10:30:03
【问题描述】:

在我的通用存储库中,我需要编写通用 Save 方法,该方法将根据 id 编辑现有实体或添加新实体。

public void Save<T>(T entity) where T : TEntity, IKeyId
{
    if (ObjectSet.Any(r => (r as IKeyId).KeyId == entity.KeyId))
    {
        Edit(entity);
    }
    else
    {
        Add(entity);
    }
}

但是当我尝试执行Any( r=&gt; (r as IKeyId)... 时,Linq 会产生异常。 不支持具有“MyProg.DAL.Appeal”类型输入和“Claimstrak.DAL.Interfaces.IKeyId”类型检查的“TypeAs”表达式。 LINQ to Entities 查询仅支持实体类型和复杂类型。

如何正确写法?

【问题讨论】:

  • 嗯,例外很明显,你不能在 linq 中使用接口转换为实体......现在,要找到解决方案,需要更多代码(了解如何以及为什么使用例如,ObjectSet)会很有用。
  • 你知道 EF 会告诉你一个实体是新的、修改的还是删除的。
  • 我知道。 Unforchenatly 我在该表中的密钥(id)不是自己的 id。列是对另一个表的引用,不是标识。

标签: asp.net-mvc linq entity-framework generics asp.net-mvc-4


【解决方案1】:

嗯,事实上你不需要使用 ObjectSet,你可以使用 DbContext 来做这件事,用一种更简单的方式。

Bu,我会说这不是一个好用的模式,在存储库中调用 Save()。我建议您在完成后才考虑 Context 的 .SaveSession(),这样您可以在往返于 te 数据库之前做很多事情。

所以,你应该创建一个这样的方法,但不要调用 SaveChanges(),而不是 Save() 方法,调用 UpdateOrInsert() 和它们,毕竟你调用了 .Save()

但我会根据您的要求给出示例(但我不推荐,我建议您将 IUnitOfWork 与 IRepository 分开)

看看代码如何很简单:

    interface IKeyId
    {
        int Id { get; set; }
    }

    DbContext context = new YourContext();

    public bool Save<TEntity>(TEntity entity) where TEntity : class, IKeyId
    {
        return (entity.Id == 0) ? Add<TEntity>(entity) : Edit<TEntity>(entity);
    }

    public bool Edit<TEntity>(TEntity entity) where TEntity : class, IKeyId
    {
        var set = context.Set<TEntity>();
        set.Attach(entity);
        return true;
    }

    public bool Add<TEntity>(TEntity entity) where TEntity : class, IKeyId
    {
        var set = context.Set<TEntity>();
        set.Add(entity);
        return true;
    }

我在我的存储库中使用了类似的方法,我已经更改了从我的数据库生成 POCO 类的 T4(.tt 文件),以明确实现我拥有的一些接口,例如 IAuditable、IValidatable 等,所以 T4在类中自动实现这些接口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-03
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2017-08-10
    相关资源
    最近更新 更多