自动/智能插入“本身”对象

时间:2013-10-03 13:24:42

标签: .net sql-server entity-framework insert

我想将UserCompany对象插入到数据库中,只需一个方法。例如将元素传递给此函数,将其取出并“插入右表”。

通常在Entity(例如LINQ to XML)中,我做的事情如下:

db.Company.UsersCompany.Add(UserCompany);
db.SubmitChanges();

但问题是我需要在使用UsersCompany之前指定表Company.Add()。 我想(因为我想为每种类型的对象/表插入一个函数)摆脱这个。如有:

UserCompany.InsertMySelf();

db.SmartAdd(UserCompany);

它知道如何自动插入表格,地点和方式。

有可能这样做吗?有没有策略?

3 个答案:

答案 0 :(得分:2)

你可以用泛型来解决这个问题:

Public Sub AddEntities(Of TEntity)(entities As IEnumerable(Of TEntity))
   For Each ent In entities
       _db.Set(Of TEntity).Add(ent)
   Next
   _db.SaveChanges()
End Sub

抱歉使用VB ...    在C#中:

public void AddEntities<TEntity>(IEnumerable<TEntity> entities)
   {
     foreach(ent in entities)
     {
         _db.Set<TEntity>.Add(ent);
     }
     _db.SaveChanges();
   }

答案 1 :(得分:1)

Controller中为您自己定义一个存储库:

public class CompanyController : ApiController
{
    private readonly CompanyRepository _companyRepository;

    public CompanyController()
    {
        _companyRepository= new CompanyRepository(User);
    }

    [HttpPost]
    public Company PostCompany(Company comp)
    {
        _companyRepository.SmartAdd(comp);
    }
}

使用定义

定义存储库
public class CompanyRepository : EFContextProvider<CompanyContext>
{
    // Fields which can be used for security within the repository.
    public IPrincipal User { get; private set; }
    public string UserName { get; set; }

    public CompanyRepository (IPrincipal user)
    {
        User = user;
        UserName = user.Identity.Name;
    }

    public DbQuery<Object> SmartAdd(Object obj)
    {
        switch (obj.GetType)
        {
            case "":  // TODO...
              Context.Company.UsersCompany.Add(UserCompany);
                break;

            default:
                break;
        }
    }

必须有一些适应性来满足你自己的需求,但这是一般的想法。

虽然交换机中可能存在很多情况,但我认为你会做对象验证和其他事情,所以你也可以在这里轻松做到。

相关链接:

答案 2 :(得分:0)

您需要查看通用存储库。此模式通过一个基类为所有CRUD提供信息。然后,您可以从此类继承以在必要时实现自定义存储库

public class RepositoryBase<T> : IRepository<T> where T : ModelBase
{
    private readonly IUnitOfWork _UnitOfWork;
    //https://stackoverflow.com/questions/4442828/entity-framework-4-ctp-4-ctp-5-generic-repository-pattern-and-unit-testable/4458250#4458250


    protected MyContext Context { get { return _UnitOfWork.Context; } }

    public RepositoryBase(IUnitOfWork unitOfWork)
    {
        _UnitOfWork = unitOfWork;
    }

    public virtual T InsertOrUpdate(T e)
    {
        DbSet<T> dbSet = Context.Set<T>();

        DbEntityEntry<T> entry;
        if (e.GetType().BaseType != null && e.GetType().Namespace == "System.Data.Entity.DynamicProxies")
        {
            //The entity being added is already a proxy type that supports lazy loading
            //just get the context entry
            entry = Context.Entry(e);
        }
        else
        {
            //The entity being added has been created using the "new" operator. 
            //Generate a proxy type to support lazy loading  and attach it
            T instance = dbSet.Create();
            instance.ID = e.ID;
            entry = Context.Entry(instance);
            dbSet.Attach(instance);

            //and set it's values to those of the entity
            entry.CurrentValues.SetValues(e);
            e = instance;
        }

        entry.State = e.ID == default(int) ?
                                EntityState.Added :
                                EntityState.Modified;

        return e;
    }

    public virtual IQueryable<T> All
    {
        get
        {
            return Context.Set<T>(); 
        }
    }

    public virtual IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = All;
        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }
        return query;
    }

    public virtual T Find(int id)
    {
        T e = Context.Set<T>().Find(id);
        if (e == null)
            return null;

        return e;
    }

    public virtual void Delete(int id)
    {
        var e = Context.Set<T>().Find(id);

        if (e != null)
            Context.Set<T>().Remove(e);

    }
}

public abstract class ModelBase
{
    public int ID { get; set; }
}

参考文献:

The repository and unit of work patterns

John Papa's original source

How to ensure proxies are created when using the repository pattern

Generic Repository Pattern