【问题标题】:Castle ActiveRecord Save() will update but not createCastle ActiveRecord Save() 将更新但不会创建
【发布时间】:2010-04-12 22:42:14
【问题描述】:

我正在更新一个程序并向数据库中添加一个新表。该程序使用 Castle 的 ActiveRecord 和存储库。我已经设置了类和存储库,并且可以很好地从数据库中获取测试用例。但是,当我尝试向数据库添加新记录时,什么也没有发生。没有错误,也没有新记录。如果我从数据库中取出测试用例并更改某些内容然后调用 Save(),则数据库中的记录会更改。

这是我用来测试的代码:

ICountryRepository _countryRepository = Country.GetRepository(site.Id);

//get test case and update
Country c = _countryRepository.FindById(1).Value;
c.Name = "c";
_countryRepository.Save(c);

//create new Country and save
Country d = new Country();
d.Id = 2;
d.Name = "d";
_countryRepository.Save(d);

现在因为它是一个维护项目,没有时间停下来研究 Castle 框架是如何做所有事情的,所以我边做边学。我已经通过研究其余代码来了解如何做事,并且在代码中有时上面的代码已用于创建新记录,所以我确信 Save() 是正确的调用函数。

我尝试将创建代码与将对象插入不同表的另一部分代码一起放入,以确保没有不同级别的权限在起作用。我添加的表和我的代码所基于的表在数据库中没有区别。

正如我所说,我在这里使用 ActiveRecord 和 Castle 框架的经验很少,它可能/将会非常简单。所以希望有人能指出来。

谢谢。

编辑:

国家级:

[ActiveRecord("Country")]
[SearchEntity]
public class Country : AbstractEntity<Country, ICountryRepository>
{
    int _countryId;
    string _name;
    int _action;

    [PrimaryKey("CountryId")]
    public int Id
    {
        get { return _countryId; }
        set { _countryId = value; }
    }

    [SearchProperty]
    [Property(Length = 100)]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    [Property]
    public int PostRegisterActionId
    {
        get { return _action; }
        set { _action = value; }
    }
}

AbstractRepository 因为 CountryRepository 目前什么都不做:

[Transient]
public abstract class AbstractRepository<T> : IRepository<T> where T : AbstractEntity, new()
{
    #region Private Vars
    protected FutureQueryRunner _futureQueryRunner;
    protected IDynamicSearchService _dynamicSearchService;
    protected bool _caching;
    protected int _cachedPages;
    protected CachingFutureQueryOfList<T> _cachedQuery;
    protected IServiceBus _serviceBus;
    private string _entityTypeName = string.Empty;
    #endregion

    #region Constructors
    public AbstractRepository(IDynamicSearchService dynamicSearchService, IServiceBus serviceBus)
    {
        _dynamicSearchService = dynamicSearchService;
        _serviceBus = serviceBus;
    }
    #endregion

    #region Public Methods
    public virtual void Save(T instance)
    {
        ActiveRecordMediator<T>.Save(instance);
    }

    public virtual void Create(T instance)
    {
        ActiveRecordMediator<T>.Create(instance);
    }

    public void Delete(T instance)
    {
        ActiveRecordMediator<T>.Delete(instance);
    }

    public virtual IFutureQueryOf<T> New()
    {
        return new NullFutureQuery<T>();
    }

    public virtual IFutureQueryOf<T> FindById(int id/*, params string[] eagerAssociations*/) // eager associations buggy
    {
        DetachedCriteria criteria = GetDefaultCriteria()
                .Add(Expression.IdEq(id));

        /*foreach (string eager in eagerAssociations)
            criteria.SetFetchMode(eager, NHibernate.FetchMode.Eager);*/

        return new FutureQueryOf<T>(_futureQueryRunner)
            .SetCriteria(criteria);
    }

    public virtual IFutureQueryOfList<T> FindAll(string sortBy, bool sortAsc)
    {
        DetachedCriteria criteria = GetDefaultCriteria();

        if (!string.IsNullOrEmpty(sortBy))
            criteria.AddOrder(sortAsc ? NHibernate.Criterion.Order.Asc(sortBy) : NHibernate.Criterion.Order.Desc(sortBy));

        return new FutureQueryOfList<T>(_futureQueryRunner)
            .SetCriteria(criteria);
    }

    public virtual IFutureQueryOfList<T> FindAll(int page, int resultsPerPage, string sortBy, bool sortAsc)
    {
        return FindAll(new DefaultCriteriaProvider<T>(DetachedCriteria.For<T>()),
            page,
            resultsPerPage,
            sortBy,
            sortAsc,
            "FindAll");
    }

    public virtual IFutureQueryOfList<T> FindAll(string searchString, int page, int resultsPerPage, string sortBy, bool sortAsc)
    {
        return FindAll(new SearchStringCriteriaProvider<T>(_dynamicSearchService, searchString),
            page,
            resultsPerPage,
            sortBy,
            sortAsc,
            "FindAllSearchString_" + searchString);
    }

    public virtual IFutureQueryOfList<T> FindAll(IListFilter filter, int page, int resultsPerPage, string sortBy, bool sortAsc)
    {
        return FindAll(new FilterCriteriaProvider<T>(_dynamicSearchService, filter),
            page,
            resultsPerPage,
            sortBy,
            sortAsc,
            "FindAllListFilter"); // TODO - the cache key needs to represent individual filters
    }

    public virtual IFutureQueryOf<int> GetCount(string searchString)
    {
        return new FutureQueryOf<int>(_futureQueryRunner)
            .SetCriteria(AddDefaultCriteria(new SearchStringCriteriaProvider<T>(_dynamicSearchService, searchString).GetDetachedCriteria())
                .SetProjection(Projections.RowCount()));
    }

    public virtual IFutureQueryOf<int> GetCount()
    {
        return new FutureQueryOf<int>(_futureQueryRunner)
            .SetCriteria(GetDefaultCriteria()
                .SetProjection(Projections.RowCount()));
    }

    public virtual string EntityType
    {
        get
        {
            if (string.IsNullOrEmpty(_entityTypeName))
                _entityTypeName = typeof(T).Name;
            return _entityTypeName;
        }
    }

    public IRepository<T> EnableCaching(bool caching)
    {
        _caching = caching;
        return this;
    }

    public IRepository<T> WithPagesToCache(int cachedPages)
    {
        _cachedPages = cachedPages;
        return this;
    }

    public virtual IRepository<T> ForSite(int siteId)
    {
        return this;
    }

    public IRepository<T> RunFutureQueriesWith(FutureQueryRunner futureQueryRunner)
    {
        _futureQueryRunner = futureQueryRunner;
        return this;
    }
    #endregion

    #region Protected Methods
    protected virtual DetachedCriteria AddDefaultCriteria(DetachedCriteria criteria)
    {
        return criteria;
    }
    protected DetachedCriteria GetDefaultCriteria()
    {
        return AddDefaultCriteria(DetachedCriteria.For<T>());
    }
    protected IFutureQueryOf<U> NewQueryOf<U>(DetachedCriteria criteria)
    {
        return new FutureQueryOf<U>(_futureQueryRunner).SetCriteria(criteria);
    }
    protected IFutureQueryOfList<U> NewQueryOfList<U>(DetachedCriteria criteria)
    {
        return new FutureQueryOfList<U>(_futureQueryRunner).SetCriteria(criteria);
    }
    #endregion

    #region Private Methods
    private IFutureQueryOfList<T> FindAll(ICriteriaProvider<T> criteriaProvider, int page, int resultsPerPage, string sortBy, bool sortAsc, string cacheKey)
    {
        CachingFutureQueryOfList<T> rtnVal = null;
        bool cached = false;
        if (_cachedQuery != null && _caching)
        {
            rtnVal = _cachedQuery;
            cached = rtnVal.SetPage(page, sortBy, sortAsc, cacheKey);
        }
        if (!cached)
        {
            rtnVal = new CachingFutureQueryOfList<T>(_futureQueryRunner, page, _cachedPages, resultsPerPage, cacheKey)
                .SetCriteria(AddDefaultCriteria(criteriaProvider.GetDetachedCriteria()), sortBy, sortAsc);

            if (_caching)
                _cachedQuery = rtnVal;
        }
        return rtnVal;
    }
    #endregion

    #region Criteria Providers
    private interface ICriteriaProvider<U>
    {
        DetachedCriteria GetDetachedCriteria();
    }

    private class DefaultCriteriaProvider<U> : ICriteriaProvider<U>
    {
        private DetachedCriteria _criteria;
        public DefaultCriteriaProvider(DetachedCriteria criteria)
        {
            _criteria = criteria;
        }
        public DetachedCriteria GetDetachedCriteria()
        {
            return _criteria;
        }
    }

    private class SearchStringCriteriaProvider<U> : ICriteriaProvider<U>
    {
        private IDynamicSearchService _searchService;
        private string _searchString;
        public SearchStringCriteriaProvider(IDynamicSearchService searchService, string searchString)
        {
            _searchService = searchService;
            _searchString = searchString;
        }
        public DetachedCriteria GetDetachedCriteria()
        {
            return _searchService.GetDetachedCriteria<U>(_searchString);
        }
    }

    private class FilterCriteriaProvider<U> : ICriteriaProvider<U>
    {
        private IDynamicSearchService _searchService;
        private IListFilter _filter;
        public FilterCriteriaProvider(IDynamicSearchService searchService, IListFilter filter)
        {
            _searchService = searchService;
            _filter = filter;
        }
        public DetachedCriteria GetDetachedCriteria()
        {
            return _searchService.GetDetachedCriteria<U>(_filter);
        }
    }
    #endregion
}

【问题讨论】:

    标签: c# .net repository castle-activerecord


    【解决方案1】:

    如果您明确设置 Country PK,就像您正在做的那样,您可能需要调用 Create() 而不是 Save()(我不知道您的存储库实现是否公开了这一点)。

    如果这不起作用,请发布您的类映射和存储库实现。

    【讨论】:

    • Create() 最初不可用,但我已将其添加到抽象存储库中。现在它抱怨一个NULL CountryId,但问题中的代码将它设置为2,所以我不确定它为什么抱怨。存储库只需调用 ActiveRecordMediator.Save/Create()。我确信 Save() 必须完成这项工作,因为它在代码的其他地方完成。哪些特定的代码会有所帮助,以便我可以将它们添加到问题中?
    • 类映射和存储库实现
    • 您使用的是什么 DBMS?通常,当未定义 PK 生成器时,它默认为 DB 生成的 PK(例如 SQL Server 的标识)。如果是这种情况,您不得为新实例设置 PK。
    • SQL Server 2005 是 DBMS。我试过删除数据库中的 PK 但没有效果。删除类中字段的属性会在运行时引发错误。
    • 不...我的意思是设置 PK 值,例如国家.Id = 2;如果 PK 是 DB 生成的,那么您的程序设置它没有任何意义。
    猜你喜欢
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多