2

我想创建一个通用 C# 类,其方法将使用实体框架向数据库添加一行。

我有一张桌子叫Address. 我编写了以下代码来向数据库添加地址:

public class AddressExchange
{
    public int Insert(Address address)
    {
        using (var db = new DemoWebEntities())
        {
            //db.AddObject("Address", address);
            db.Addresses.AddObject(address);
            db.SaveChanges();
            return address.Id;
        }
    }
}

我想编写一个通用类,它将为我的 EDMX 中的任何实体执行此操作。我认为它应该看起来像这样:

public class EntityExchange<T, KeyType>
{
    public KeyType Insert(T t)
    {
        using (var db = new DemoWebEntities())
        {
            // The entity set name might be wrong.
            db.AddObject(typeof(T).Name, t);                

            // EF doesn't know what the primary key is.
            return t.Id;
        }
    }
}

我觉得可以用AddObject方法把对象添加到数据库中,但是entityset名不一定和类型名一样,特别是已经复数的情况下!

我也想将主键返回给调用者,但我不知道如何判断哪个字段包含主键。

4

4 回答 4

3

我在通用存储库中有一个通用的 InsertOrUpdate 方法,该方法还可以确保创建代理。(代理需要支持延迟加载,如果您使用“new”创建实体,则不会创建代理)。在这里查看问题

public class RepositoryBase<T> : IRepository<T> where T : ModelBase
{
    public virtual T InsertOrUpdate(T e)
    {
        DbSet<T> dbSet = context.Set<T>();

        //Generate a proxy type to support lazy loading
        T instance = dbSet.Create();

        DbEntityEntry<T> entry;
        if (e.GetType().Equals(instance.GetType()))
        {
            //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. 
            //Attach the proxy
            //Need to set the ID before attaching or we get 
            //The property 'ID' is part of the object's key 
            //information and cannot be modified when we call SetValues
            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 abstract class ModelBase
{
    public int ID { get; set; }
}

请注意,所有模型都继承 ModelBase 以便处理 ID 问题,并且我返回实体而不仅仅是 ID。这可能不是绝对必要的,因为传入了对实体的引用,并且 EF 无论如何都会对 ID 执行修复,因此您始终可以从传入的引用访问它。

于 2013-07-20T09:48:28.530 回答
2

这可能依赖于实体框架上的特定版本,但这就是我的做法

public void Create(T entity)
{
    using (var db = new DemoWebEntities())
    {
        db.Set<T>().Add(entity);
    }
}
于 2013-07-19T14:53:18.537 回答
0

也许它可以帮助你。

public T Add(T model)
    {
        using (BigConceptEntities entity = new BigConceptEntities())
        {
            entity.Set<T>().Add(model);
            entity.SaveChanges();
            return model;
        }
    }
于 2014-11-26T07:47:36.490 回答
0

对于主键问题,您可以使用部分类来使您的实体实现接口,如下所示:

public interface IEntity
{
    Guid PrimaryKey { get; }
}

然后,您的实体类将返回适当的值:

public partial class EntityType : IEntity
{
    public Guid PrimaryKey
    {
        get
        {
            return this.WhateverId; // Return the primary key
        }
     }
}

然后,将您的方法限制为仅接受 IEntity:

public class EntityExchange<T, KeyType> where T : IEntity

最后在插入后返回主键:

return t.PrimaryKey;
于 2013-07-19T14:57:52.147 回答