3

私が構築しているものは、非常にユニークなものではありません。一言で言えば、ASP.NET MVC 4 (Web Api) と Entity Framework 5 (空間サポート付き) を使用して、Azure で実行される小さな FourSquare のようなサービスを作成しています。そのため、MongoDB や CouchDB などの NoSQL データベースではなく、SQL Azure を使用しています。部分的には、私が .NET に流暢で慣れているため、開発経験 (リファクタリング、展開、テスト) が何であるかを確認するためと、たとえば. node.js/MongoDB。

それでは、いくつかのコードを見てみましょう。

/// <summary>
/// Return the nearest locations relative from the given longitude/latitude
/// </summary>
/// <param name="longitude">Longitude</param>
/// <param name="latitude">Latitude</param>
/// <param name="maxresults">Optional maximum results, default is 2</param>
/// <param name="radius">Optional maximum radius in kilometres, default is 50 km</param>
/// <returns></returns>
public JsonEnvelope Get(string longitude, string latitude, int maxresults = 2, int radius = 50)
{
    var pointTxt = string.Format("POINT({0} {1})", longitude, latitude);
    var locations = (from s in locationEntityRepository.GetAll
                     orderby s.Coordinates.Distance(DbGeography.FromText(pointTxt))
                     where s.Coordinates.Distance(DbGeography.FromText(pointTxt)) / 1000  <= radius
                     select new Location
                     {
                         Id = s.Id,
                         Name = s.Name,
                         LocationType = s.LocationType,
                         Address = s.Address,
                         Longitude = s.Coordinates.Longitude.Value,
                         Latitude = s.Coordinates.Latitude.Value,
                         Distance = (s.Coordinates.Distance(DbGeography.FromText(pointTxt)).Value) / 1000
                      })
                    .Take(maxresults).ToList();

    // Bad bad bad. But EF/Linq doesn't let us do Includes when using subqueries... Go figure
    foreach (var location in locations)
    {
        location.Checkins = AutoMapper.
                            Mapper.
                            Map<List <Checkin>, List<LocationCheckinsJsonViewModel>>
                                (checkinRepository.GetCheckinsForLocation(location.Id).ToList());
    }

    // AutoMapper.Mapper.Map<Checkin, CheckinViewModel>(dbCheckin);
    var jsonBuilder = new JsonResponseBuilder();
    jsonBuilder.AddObject2Response("locations", locations);

    return jsonBuilder.JsonEnvelope;
}

いくつか明確にする必要があると思います。locationEntityRepository.GetAll見た目はこんな感じ。

public IQueryable<LocationEntity> GetAll
{
    get { return _context.Locations; }
}

public IQueryable<LocationEntity> GetAllIncluding(params Expression<Func<LocationEntity, object>>[] includeProperties)
{
    IQueryable<LocationEntity> query = _context.Locations;
    foreach (var includeProperty in includeProperties) {
        query = query.Include(includeProperty);
    }

    // var tmp = query.ToList();

    return query;
}

今、コードは本当にファンキーなにおいがします。理想的には、メソッドのGetAllIncluding(c => c.Checkins)代わりにan を使用し、LINQ プロジェクション内でマップするために使用できるようにしたいと考えています。GetAllAutoMapper

サブクエリを使用すると、Include + LINQ/EF が意図的に null を返すのは設計によるものです。また、LINQ/EF クエリで automapper を使用するには、 を使用する必要がありますが、Project().To<>を使用すると機能しません.ForMember

したがって、課題はコードをより効率的にすることです (SQL を減らし、JSON 構造の変更が必要な場合の保守を容易にします。覚えておいてください、ここでは node.js/MongoDB を打ち負かそうとしているのです ;)は?

4

3 に答える 3

1

リポジトリ パターンを使用して同様のことを行いました。

    public IEnumerable<T> FindAll()
    {
        return _context.Set<T>().ToList();
    }

    public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
    {
        return _context.Set<T>().Where(predicate);
    }

.Set メソッドは

    public IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        return base.Set<TEntity>();
    }

これにより、データベースからタイプのすべてを取得するか、特定の基準を満たすすべてのタイプを取得することができます。

これにより、オブジェクトのリストが残ります。または、FirstOrDefault() を使用する場合は、必要に応じてマップできる単一のオブジェクトが残ります。

于 2013-03-11T20:25:18.343 に答える
0

なぜこれを使用しないのですか?

Context context=new Context();
Public List<LocationEntity> GetAll()
{
    return context.LocationEntities.Include("includeProperty").ToList();
}

そしてコンテキストはこれです:

public class Context: DbContext
    {
        public Context()
        {
            base.Configuration.LazyLoadingEnabled = false;
            base.Configuration.ProxyCreationEnabled = false;
            base.Configuration.ValidateOnSaveEnabled = false;
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
        public DbSet<LocationEntity> LocationEntities{ get; set; }
    }
于 2013-03-17T20:20:56.687 に答える